ngx-virtual-dnd 3.2.1 → 3.3.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/fesm2022/ngx-virtual-dnd.mjs +1839 -656
- package/fesm2022/ngx-virtual-dnd.mjs.map +1 -1
- package/package.json +1 -1
- package/types/ngx-virtual-dnd.d.ts +62 -26
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ngx-virtual-dnd.mjs","sources":["../../../projects/ngx-virtual-dnd/src/lib/models/drag-drop.models.ts","../../../projects/ngx-virtual-dnd/src/lib/strategies/fixed-height.strategy.ts","../../../projects/ngx-virtual-dnd/src/lib/utils/height-cache.ts","../../../projects/ngx-virtual-dnd/src/lib/strategies/dynamic-height.strategy.ts","../../../projects/ngx-virtual-dnd/src/lib/tokens/scroll-container.token.ts","../../../projects/ngx-virtual-dnd/src/lib/tokens/virtual-viewport.token.ts","../../../projects/ngx-virtual-dnd/src/lib/tokens/animation-config.token.ts","../../../projects/ngx-virtual-dnd/src/lib/services/drag-state.service.ts","../../../projects/ngx-virtual-dnd/src/lib/utils/attribute-selectors.ts","../../../projects/ngx-virtual-dnd/src/lib/services/position-calculator.service.ts","../../../projects/ngx-virtual-dnd/src/lib/services/drag-scheduler.service.ts","../../../projects/ngx-virtual-dnd/src/lib/services/auto-scroll.service.ts","../../../projects/ngx-virtual-dnd/src/lib/services/element-clone.service.ts","../../../projects/ngx-virtual-dnd/src/lib/services/keyboard-drag.service.ts","../../../projects/ngx-virtual-dnd/src/lib/services/overlay-container.service.ts","../../../projects/ngx-virtual-dnd/src/lib/services/drag-index-calculator.service.ts","../../../projects/ngx-virtual-dnd/src/lib/components/drag-placeholder.component.ts","../../../projects/ngx-virtual-dnd/src/lib/utils/dom-signal-bindings.ts","../../../projects/ngx-virtual-dnd/src/lib/utils/auto-scroll-registration.ts","../../../projects/ngx-virtual-dnd/src/lib/utils/shift-animator.ts","../../../projects/ngx-virtual-dnd/src/lib/components/virtual-scroll-container.component.ts","../../../projects/ngx-virtual-dnd/src/lib/utils/drop-animator.ts","../../../projects/ngx-virtual-dnd/src/lib/components/drag-preview.component.ts","../../../projects/ngx-virtual-dnd/src/lib/components/placeholder.component.ts","../../../projects/ngx-virtual-dnd/src/lib/directives/droppable-group.directive.ts","../../../projects/ngx-virtual-dnd/src/lib/utils/group-resolution.ts","../../../projects/ngx-virtual-dnd/src/lib/utils/drop-index-normalization.ts","../../../projects/ngx-virtual-dnd/src/lib/directives/droppable.directive.ts","../../../projects/ngx-virtual-dnd/src/lib/components/virtual-sortable-list.component.ts","../../../projects/ngx-virtual-dnd/src/lib/components/virtual-viewport.component.ts","../../../projects/ngx-virtual-dnd/src/lib/directives/content-header.directive.ts","../../../projects/ngx-virtual-dnd/src/lib/components/virtual-content.component.ts","../../../projects/ngx-virtual-dnd/src/lib/handlers/keyboard-drag.handler.ts","../../../projects/ngx-virtual-dnd/src/lib/utils/interactive-elements.ts","../../../projects/ngx-virtual-dnd/src/lib/handlers/pointer-drag.handler.ts","../../../projects/ngx-virtual-dnd/src/lib/directives/draggable.directive.ts","../../../projects/ngx-virtual-dnd/src/lib/directives/scrollable.directive.ts","../../../projects/ngx-virtual-dnd/src/lib/directives/virtual-for.directive.ts","../../../projects/ngx-virtual-dnd/src/lib/utils/drop-helpers.ts","../../../projects/ngx-virtual-dnd/src/lib/index.ts","../../../projects/ngx-virtual-dnd/src/public-api.ts","../../../projects/ngx-virtual-dnd/src/ngx-virtual-dnd.ts"],"sourcesContent":["/**\n * Represents the item currently being dragged.\n */\nexport interface DraggedItem {\n /** Unique identifier for the draggable item */\n draggableId: string;\n /** ID of the droppable container the item originated from */\n droppableId: string;\n /** Reference to the dragged element */\n element: HTMLElement;\n /** Cloned element for use in drag preview (auto-generated) */\n clonedElement?: HTMLElement;\n /** Height of the dragged element in pixels */\n height: number;\n /** Width of the dragged element in pixels */\n width: number;\n /** Optional user-provided data associated with the item */\n data?: unknown;\n}\n\n/**\n * Current position of the cursor during drag.\n */\nexport interface CursorPosition {\n x: number;\n y: number;\n}\n\n/**\n * Offset from cursor to the top-left corner of the dragged element.\n * Used to maintain grab position during drag.\n */\nexport interface GrabOffset {\n x: number;\n y: number;\n}\n\n/**\n * Complete state of the drag-and-drop system.\n */\nexport interface DragState {\n /** Whether a drag operation is currently in progress */\n isDragging: boolean;\n /** Information about the item being dragged */\n draggedItem: DraggedItem | null;\n /** ID of the droppable where the drag started */\n sourceDroppableId: string | null;\n /** Original index of the dragged item in the source list */\n sourceIndex: number | null;\n /** ID of the droppable currently being hovered over */\n activeDroppableId: string | null;\n /**\n * `END_OF_LIST` while a droppable is targeted, otherwise null.\n * @deprecated It never identifies an item. Use `placeholderIndex`. Will be removed in the next\n * major version.\n */\n placeholderId: string | null;\n /** Index where the placeholder should be inserted */\n placeholderIndex: number | null;\n /** Current cursor position */\n cursorPosition: CursorPosition | null;\n /** Offset from cursor to element top-left (for maintaining grab position) */\n grabOffset: GrabOffset | null;\n /** Position when drag started (for axis locking) */\n initialPosition: CursorPosition | null;\n /** Axis to freeze ('x' = X frozen → vertical-only, 'y' = Y frozen → horizontal-only) */\n lockAxis: 'x' | 'y' | null;\n /** Whether this is a keyboard-initiated drag */\n isKeyboardDrag: boolean;\n /** Target index during keyboard navigation */\n keyboardTargetIndex: number | null;\n}\n\n/**\n * Event emitted when a drag operation starts.\n */\nexport interface DragStartEvent {\n /** Unique identifier for the draggable item */\n draggableId: string;\n /** ID of the droppable container the item originated from */\n droppableId: string;\n /** Optional user-provided data associated with the item */\n data?: unknown;\n /** Position where the drag started */\n position: CursorPosition;\n /** 0-indexed position in the source list (for screen reader announcements) */\n sourceIndex: number;\n}\n\n/**\n * Source information for a drop event.\n */\nexport interface DropSource {\n /** Unique identifier for the draggable item */\n draggableId: string;\n /** ID of the droppable container the item originated from */\n droppableId: string;\n /** Original index in the source list */\n index: number;\n /** Optional user-provided data associated with the item */\n data?: unknown;\n}\n\n/**\n * Destination information for a drop event.\n */\nexport interface DropDestination {\n /** ID of the droppable container receiving the item */\n droppableId: string;\n /**\n * The library always sets `END_OF_LIST`.\n * @deprecated It never identifies an item. Use `index` for the insertion position. Will be\n * removed in the next major version.\n */\n placeholderId: string;\n /** Target index in the destination list */\n index: number;\n /** Optional user-provided data associated with the droppable */\n data?: unknown;\n}\n\n/**\n * Event emitted when an item is dropped.\n */\nexport interface DropEvent {\n /** Information about where the item came from */\n source: DropSource;\n /** Information about where the item is going */\n destination: DropDestination;\n}\n\n/**\n * Event emitted by a droppable each time the placeholder moves within it during a drag,\n * i.e. whenever items are displaced. Useful for haptic feedback on every step.\n *\n * Indexes use the same convention as `DropEvent.destination.index` (the insertion index\n * the item would get if dropped now). Not emitted for the placeholder's initial position\n * at drag start, nor when the placeholder leaves this droppable.\n */\nexport interface PlaceholderMoveEvent {\n /** Unique identifier for the dragged item */\n draggableId: string;\n /** ID of the droppable container the item originated from */\n sourceDroppableId: string;\n /** ID of the droppable the placeholder moved within */\n droppableId: string;\n /**\n * Previous insertion index in this droppable, or `null` when the placeholder just entered\n * it from elsewhere. For the first move in the source list this is the item's own index.\n */\n previousIndex: number | null;\n /** New insertion index in this droppable */\n currentIndex: number;\n /** Optional user-provided data associated with the dragged item */\n data?: unknown;\n}\n\n/**\n * Event emitted when a drag operation ends (including cancel).\n */\nexport interface DragEndEvent {\n /** Unique identifier for the draggable item */\n draggableId: string;\n /** ID of the droppable container the item originated from */\n droppableId: string;\n /**\n * Whether the drag was cancelled: Escape, Tab during a keyboard drag, or, during a pointer\n * drag, the window losing focus, the page being hidden or the system cancelling the touch\n * (`touchcancel`). Releasing over no valid\n * target (outside any droppable, or over a disabled droppable) is NOT a cancel —\n * it reports `cancelled: false` with `destinationIndex: null`. Branch on\n * `destinationIndex === null` to detect \"no drop occurred\".\n */\n cancelled: boolean;\n /** Optional user-provided data associated with the item */\n data?: unknown;\n /** Original 0-indexed position in source list (for cancel announcements) */\n sourceIndex: number;\n /**\n * Final 0-indexed insertion position, or `null` when there is no valid drop target —\n * a cancelled drag, a release outside every droppable, or a release over a disabled\n * droppable. A non-null value pairs with a `DropEvent` on the destination.\n */\n destinationIndex: number | null;\n}\n\n/**\n * Initial state for the drag state service.\n */\nexport const INITIAL_DRAG_STATE: DragState = {\n isDragging: false,\n draggedItem: null,\n sourceDroppableId: null,\n sourceIndex: null,\n activeDroppableId: null,\n placeholderId: null,\n placeholderIndex: null,\n cursorPosition: null,\n grabOffset: null,\n initialPosition: null,\n lockAxis: null,\n isKeyboardDrag: false,\n keyboardTargetIndex: null,\n};\n\n/**\n * The value of every `placeholderId` the library sets. Positions are reported as indexes\n * (`placeholderIndex`, `DropDestination.index`).\n * @deprecated Goes with the deprecated `placeholderId` fields. Use the indexes. Will be removed in\n * the next major version.\n */\nexport const END_OF_LIST = 'END_OF_LIST';\n","import { signal } from '@angular/core';\nimport type { VirtualScrollStrategy } from '../models/virtual-scroll-strategy';\n\n/**\n * Fixed-height virtual scroll strategy.\n *\n * Wraps the existing `index * itemHeight` math with zero overhead — no cache,\n * no measurement. This is the default strategy used when `dynamicItemHeight`\n * is not enabled.\n */\nexport class FixedHeightStrategy implements VirtualScrollStrategy {\n readonly #itemHeight: number;\n\n /** Excluded index during same-list drag (-1 = none) */\n #excludedIndex = -1;\n\n /** Logical item count from setItemKeys (used by drag index calculator) */\n #itemCount = 0;\n\n /** Version signal — bumps when exclusion changes */\n readonly #version = signal(0);\n readonly version = this.#version.asReadonly();\n\n constructor(itemHeight: number) {\n this.#itemHeight = itemHeight;\n }\n\n getTotalHeight(itemCount: number): number {\n return itemCount * this.#itemHeight;\n }\n\n getFirstVisibleIndex(scrollTop: number): number {\n if (this.#itemHeight <= 0) return 0;\n return Math.floor(scrollTop / this.#itemHeight);\n }\n\n getVisibleCount(_startIndex: number, containerHeight: number): number {\n if (containerHeight <= 0 || this.#itemHeight <= 0) return 0;\n return Math.ceil(containerHeight / this.#itemHeight);\n }\n\n getOffsetForIndex(index: number): number {\n if (this.#excludedIndex >= 0 && index > this.#excludedIndex) {\n return (index - 1) * this.#itemHeight;\n }\n return index * this.#itemHeight;\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n getItemHeight(index: number): number {\n return this.#itemHeight;\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n setMeasuredHeight(key: unknown, height: number): void {\n // No-op for fixed height strategy\n }\n\n setItemKeys(keys: unknown[]): void {\n const prevCount = this.#itemCount;\n this.#itemCount = keys.length;\n if (prevCount !== this.#itemCount) {\n this.#version.update((v) => v + 1);\n }\n }\n\n setExcludedIndex(index: number | null): void {\n const newIndex = index ?? -1;\n if (this.#excludedIndex !== newIndex) {\n this.#excludedIndex = newIndex;\n this.#version.update((v) => v + 1);\n }\n }\n\n findIndexAtOffset(offset: number): number {\n if (this.#itemHeight <= 0) return 0;\n const visualIndex = Math.floor(offset / this.#itemHeight);\n // When an item is excluded (same-list drag), visual indices at or past\n // the excluded position map to logical index + 1\n if (this.#excludedIndex >= 0 && visualIndex >= this.#excludedIndex) {\n return visualIndex + 1;\n }\n return visualIndex;\n }\n\n getItemCount(): number {\n return this.#itemCount;\n }\n}\n","/**\n * Cache for measured item heights in dynamic virtual scrolling.\n *\n * Tracks heights by trackBy key (survives reordering). Maintains a cumulative\n * offset prefix-sum array, lazily rebuilt on height change. Binary search\n * O(log N) for scroll-to-index lookups.\n *\n * This is a plain class (not a service) — one instance per virtual scroll.\n */\nexport class HeightCache {\n /** Estimated height used for unmeasured items */\n readonly #estimatedHeight: number;\n\n /** Map from trackBy key to measured height */\n readonly #heightsByKey = new Map<unknown, number>();\n\n /** Current ordered list of trackBy keys (index-aligned with item array) */\n #keys: unknown[] = [];\n\n /** Prefix sums: offsets[i] = cumulative height of items 0..i-1 */\n #offsets: number[] = [];\n\n /** Whether offsets need to be rebuilt */\n #dirty = true;\n\n /** Index excluded during same-list drag (-1 = none) */\n #excludedIndex = -1;\n\n constructor(estimatedHeight: number) {\n this.#estimatedHeight = estimatedHeight;\n }\n\n /** Number of measured items */\n get measuredCount(): number {\n return this.#heightsByKey.size;\n }\n\n /** Number of logical items in the cache */\n get itemCount(): number {\n return this.#keys.length;\n }\n\n /**\n * Update the ordered list of trackBy keys.\n * This must be called whenever items change order or the array changes.\n */\n setKeys(keys: unknown[]): boolean {\n const sameOrder =\n keys.length === this.#keys.length &&\n keys.every((key, index) => Object.is(key, this.#keys[index]));\n\n const nextKeySet = new Set(keys);\n let pruned = false;\n for (const key of this.#heightsByKey.keys()) {\n if (!nextKeySet.has(key)) {\n this.#heightsByKey.delete(key);\n pruned = true;\n }\n }\n\n if (sameOrder && !pruned) {\n return false;\n }\n\n this.#keys = keys;\n this.#dirty = true;\n return true;\n }\n\n /**\n * Record a measured height for a trackBy key.\n * @returns true if the height actually changed (triggers version bump)\n */\n setHeight(key: unknown, height: number): boolean {\n const existing = this.#heightsByKey.get(key);\n if (existing === height) return false;\n this.#heightsByKey.set(key, height);\n this.#dirty = true;\n return true;\n }\n\n /**\n * Get the height for a specific index.\n * Returns measured height if available, otherwise the estimated height.\n */\n getHeight(index: number): number {\n if (index < 0 || index >= this.#keys.length) return this.#estimatedHeight;\n const key = this.#keys[index];\n return this.#heightsByKey.get(key) ?? this.#estimatedHeight;\n }\n\n /**\n * Get the pixel offset (top position) for a given item index.\n * Accounts for the excluded index during same-list drag.\n */\n getOffset(index: number): number {\n this.#rebuildIfDirty();\n\n if (this.#excludedIndex < 0) {\n // No exclusion — direct lookup\n return index < this.#offsets.length ? this.#offsets[index] : this.#getTotalHeightRaw();\n }\n\n // With exclusion: subtract the excluded item's height from offsets\n // at or after the excluded index\n if (index <= this.#excludedIndex) {\n return this.#offsets[index] ?? 0;\n }\n\n // index > excludedIndex: offset = raw offset for (index) minus excluded item's height\n const rawOffset =\n index < this.#offsets.length ? this.#offsets[index] : this.#getTotalHeightRaw();\n const excludedHeight = this.getHeight(this.#excludedIndex);\n return rawOffset - excludedHeight;\n }\n\n /**\n * Get total content height for all items.\n * Does NOT exclude the dragged item — the spacer must maintain full height\n * during same-list drag so sibling content (footers etc.) doesn't shift.\n * Uses O(1) prefix-sum lookup when possible.\n */\n getTotalHeight(itemCount: number): number {\n this.#rebuildIfDirty();\n\n if (itemCount <= 0) return 0;\n\n const keyCount = this.#keys.length;\n if (keyCount === 0) return itemCount * this.#estimatedHeight;\n\n if (itemCount >= keyCount) {\n // All known items + estimated for any extras\n return this.#getTotalHeightRaw() + (itemCount - keyCount) * this.#estimatedHeight;\n }\n\n // Partial: prefix sum up to itemCount\n return this.#offsets[itemCount - 1] + this.getHeight(itemCount - 1);\n }\n\n /**\n * Find the first visible index for a given scrollTop.\n * Uses binary search on the prefix-sum offsets (excluding the excluded item).\n */\n findFirstVisibleIndex(scrollTop: number): number {\n this.#rebuildIfDirty();\n\n const count = this.#keys.length;\n if (count === 0) return 0;\n\n // Binary search for the first item whose bottom edge is past scrollTop\n let lo = 0;\n let hi = count - 1;\n let result = 0;\n\n while (lo <= hi) {\n const mid = (lo + hi) >>> 1;\n const offset = this.getOffset(mid);\n if (offset <= scrollTop) {\n result = mid;\n lo = mid + 1;\n } else {\n hi = mid - 1;\n }\n }\n\n return result;\n }\n\n /**\n * Count visible items from startIndex within containerHeight.\n */\n getVisibleCount(startIndex: number, containerHeight: number): number {\n if (containerHeight <= 0) return 0;\n\n const count = this.#keys.length;\n let accumulated = 0;\n let visible = 0;\n let stopIndex = count;\n\n for (let i = startIndex; i < count; i++) {\n if (i === this.#excludedIndex) continue;\n accumulated += this.getHeight(i);\n visible++;\n if (accumulated >= containerHeight) {\n stopIndex = i;\n break;\n }\n }\n\n // Add 1 for partially visible items\n if (visible === 0) return 0;\n const hasMoreItems = stopIndex < count - 1;\n return hasMoreItems ? visible + 1 : visible;\n }\n\n /**\n * Find the item index at a given pixel offset.\n * Used for drag index calculations with variable heights.\n */\n findIndexAtOffset(offset: number): number {\n this.#rebuildIfDirty();\n\n const count = this.#keys.length;\n if (count === 0) return 0;\n\n if (!Number.isFinite(offset)) {\n return offset < 0 ? 0 : count;\n }\n\n if (offset <= 0) {\n if (this.#excludedIndex === 0) {\n return count > 1 ? 1 : count;\n }\n return 0;\n }\n\n const excludedIndex = this.#excludedIndex;\n if (excludedIndex < 0 || excludedIndex >= count) {\n return this.#findFirstIndexWithBottomPastOffset(offset, 0, count - 1);\n }\n\n const excludedOffset = this.#offsets[excludedIndex];\n if (offset < excludedOffset && excludedIndex > 0) {\n return this.#findFirstIndexWithBottomPastOffset(offset, 0, excludedIndex - 1);\n }\n\n if (excludedIndex >= count - 1) {\n return count;\n }\n\n const excludedHeight = this.getHeight(excludedIndex);\n return this.#findFirstIndexWithBottomPastOffset(\n offset + excludedHeight,\n excludedIndex + 1,\n count - 1,\n );\n }\n\n /**\n * Set the excluded index for same-list drag.\n */\n setExcludedIndex(index: number | null): boolean {\n const nextIndex = index ?? -1;\n if (this.#excludedIndex === nextIndex) {\n return false;\n }\n\n this.#excludedIndex = nextIndex;\n return true;\n }\n\n /**\n * Find first logical index in [start, end] whose bottom edge is past offset.\n * Returns one-past-end when no match is found.\n */\n #findFirstIndexWithBottomPastOffset(offset: number, start: number, end: number): number {\n if (start > end) {\n return start;\n }\n\n let lo = start;\n let hi = end;\n let result = end + 1;\n\n while (lo <= hi) {\n const mid = (lo + hi) >>> 1;\n const midBottom = this.#offsets[mid] + this.getHeight(mid);\n\n if (midBottom > offset) {\n result = mid;\n hi = mid - 1;\n } else {\n lo = mid + 1;\n }\n }\n\n return result;\n }\n\n /** Raw total height without exclusion */\n #getTotalHeightRaw(): number {\n this.#rebuildIfDirty();\n const len = this.#offsets.length;\n if (len === 0) return 0;\n return this.#offsets[len - 1] + this.getHeight(len - 1);\n }\n\n /** Rebuild prefix-sum array if dirty */\n #rebuildIfDirty(): void {\n if (!this.#dirty) return;\n this.#dirty = false;\n\n const count = this.#keys.length;\n if (this.#offsets.length !== count) {\n this.#offsets = new Array<number>(count);\n }\n\n let cumulative = 0;\n for (let i = 0; i < count; i++) {\n this.#offsets[i] = cumulative;\n cumulative += this.getHeight(i);\n }\n }\n}\n","import { signal, type Signal, type WritableSignal } from '@angular/core';\nimport type { VirtualScrollStrategy } from '../models/virtual-scroll-strategy';\nimport { HeightCache } from '../utils/height-cache';\n\n/**\n * Dynamic-height virtual scroll strategy.\n *\n * Uses a `HeightCache` with prefix-sum offsets and binary search for O(log N)\n * scroll-to-index lookups. Heights are tracked by trackBy key (survive\n * reordering) and auto-measured via ResizeObserver by the directive.\n *\n * The `version` signal bumps whenever heights change, causing dependent\n * computeds to re-evaluate.\n */\nexport class DynamicHeightStrategy implements VirtualScrollStrategy {\n readonly #cache: HeightCache;\n readonly #version: WritableSignal<number> = signal(0);\n\n readonly version: Signal<number> = this.#version.asReadonly();\n\n constructor(estimatedHeight: number) {\n this.#cache = new HeightCache(estimatedHeight);\n }\n\n getTotalHeight(itemCount: number): number {\n // Read version to subscribe to changes\n this.#version();\n return this.#cache.getTotalHeight(itemCount);\n }\n\n getFirstVisibleIndex(scrollTop: number): number {\n this.#version();\n return this.#cache.findFirstVisibleIndex(scrollTop);\n }\n\n getVisibleCount(startIndex: number, containerHeight: number): number {\n this.#version();\n return this.#cache.getVisibleCount(startIndex, containerHeight);\n }\n\n getOffsetForIndex(index: number): number {\n this.#version();\n return this.#cache.getOffset(index);\n }\n\n getItemHeight(index: number): number {\n this.#version();\n return this.#cache.getHeight(index);\n }\n\n setMeasuredHeight(key: unknown, height: number): void {\n const changed = this.#cache.setHeight(key, height);\n if (changed) {\n this.#version.update((v) => v + 1);\n }\n }\n\n setItemKeys(keys: unknown[]): void {\n const changed = this.#cache.setKeys(keys);\n if (changed) {\n this.#version.update((v) => v + 1);\n }\n }\n\n setExcludedIndex(index: number | null): void {\n const changed = this.#cache.setExcludedIndex(index);\n if (changed) {\n this.#version.update((v) => v + 1);\n }\n }\n\n findIndexAtOffset(offset: number): number {\n this.#version();\n return this.#cache.findIndexAtOffset(offset);\n }\n\n getItemCount(): number {\n this.#version();\n return this.#cache.itemCount;\n }\n}\n","import { InjectionToken } from '@angular/core';\n\n/**\n * Interface for a scroll container that can be used with VirtualForDirective.\n * Implement this interface to create custom scroll containers.\n *\n * The scrollTop() and containerHeight() methods should return reactive values\n * (internally backed by signals) so that changes trigger re-computation in\n * the virtual scroll directive.\n */\nexport interface VdndScrollContainer {\n /** The native HTML element that handles scrolling */\n readonly nativeElement: HTMLElement;\n\n /** Current scroll position from top in pixels (reactive) */\n scrollTop(): number;\n\n /** Current container height in pixels (reactive) */\n containerHeight(): number;\n\n /** Scroll to a specific position */\n scrollTo(options: ScrollToOptions): void;\n}\n\n/**\n * Injection token for providing a scroll container to VirtualForDirective.\n *\n * Use the `vdndScrollable` directive to provide this token, or implement\n * `VdndScrollContainer` and provide it manually.\n *\n * @example\n * ```html\n * <div vdndScrollable style=\"overflow: auto; height: 400px;\">\n * <ng-container *vdndVirtualFor=\"let item of items(); itemHeight: 50; trackBy: trackById\">\n * <div>{{ item.name }}</div>\n * </ng-container>\n * </div>\n * ```\n */\nexport const VDND_SCROLL_CONTAINER = new InjectionToken<VdndScrollContainer>(\n 'VDND_SCROLL_CONTAINER'\n);\n","import { InjectionToken } from '@angular/core';\nimport type { VirtualScrollStrategy } from '../models/virtual-scroll-strategy';\n\n/**\n * Interface for a virtual viewport that provides wrapper-based positioning.\n * Components implementing this interface provide a content wrapper with\n * GPU-accelerated transform positioning for efficient virtual scrolling.\n */\nexport interface VdndVirtualViewport {\n /** Current scroll position */\n scrollTop(): number;\n\n /** Height of the viewport container */\n containerHeight(): number;\n\n /** Height of each item in pixels */\n itemHeight(): number;\n\n /** Offset for content below headers (page-level scroll scenarios) */\n contentOffset(): number;\n\n /** The native element of the viewport */\n readonly nativeElement: HTMLElement;\n\n /**\n * Called by VirtualForDirective to inform the viewport of the actual\n * first rendered item index (accounting for overscan). The viewport\n * uses this to position the content wrapper correctly.\n */\n setRenderStartIndex(index: number): void;\n\n /**\n * Get the pixel offset for a given item index.\n * Uses the strategy pattern to support both fixed and dynamic heights.\n */\n getOffsetForIndex(index: number): number;\n\n /**\n * The virtual scroll strategy used by this viewport.\n * Available for drag-drop integration and external consumers.\n */\n readonly strategy: VirtualScrollStrategy | null;\n}\n\n/**\n * Injection token for virtual viewport.\n * VirtualForDirective optionally injects this to detect if it's inside\n * a viewport component that handles wrapper-based positioning.\n */\nexport const VDND_VIRTUAL_VIEWPORT = new InjectionToken<VdndVirtualViewport>(\n 'VDND_VIRTUAL_VIEWPORT',\n);\n\n/**\n * Internal, not exported from the package. Provided by vdnd-virtual-viewport next to\n * VDND_VIRTUAL_VIEWPORT: its rows start contentOffset px down its scroll area while its\n * scrollTop() is the raw position, so VirtualForDirective subtracts the offset when the viewport\n * it injects is this one. A token instead of an instanceof check keeps the viewport component out\n * of apps that don't use it.\n */\nexport const VDND_OFFSET_ROWS_VIEWPORT = new InjectionToken<VdndVirtualViewport>(\n 'VDND_OFFSET_ROWS_VIEWPORT',\n);\n","import { InjectionToken } from '@angular/core';\n\n/**\n * Animation settings for drag-and-drop lists.\n */\nexport interface VdndAnimationConfig {\n /**\n * Duration (ms) of the slide animation played when items are displaced by the\n * placeholder during a drag. `0` disables the animation.\n * @default 200\n */\n shiftDuration?: number;\n\n /**\n * CSS easing function for the shift animation.\n * @default 'cubic-bezier(0.2, 0, 0, 1)'\n */\n shiftEasing?: string;\n\n /**\n * Duration (ms) of the drop animation: on drop or cancel, the drag preview glides into\n * the dropped item's final position instead of disappearing. `0` disables it.\n * @default 200\n */\n dropDuration?: number;\n\n /**\n * CSS easing function for the drop animation.\n * @default 'cubic-bezier(0.2, 0, 0, 1)'\n */\n dropEasing?: string;\n}\n\n/** Default shift animation duration (ms) used when the config omits `shiftDuration`. */\nexport const DEFAULT_SHIFT_DURATION = 200;\n\n/** Default shift animation easing used when the config omits `shiftEasing`. */\nexport const DEFAULT_SHIFT_EASING = 'cubic-bezier(0.2, 0, 0, 1)';\n\n/** Default drop animation duration (ms) used when the config omits `dropDuration`. */\nexport const DEFAULT_DROP_DURATION = 200;\n\n/** Default drop animation easing used when the config omits `dropEasing`. */\nexport const DEFAULT_DROP_EASING = 'cubic-bezier(0.2, 0, 0, 1)';\n\n/**\n * Opt-in animation configuration. When provided, items displaced by the placeholder\n * slide into their new position instead of jumping, and on drop the drag preview glides\n * into the item's final position. Resolved through the element\n * injector, so it can be provided app-wide or per component subtree.\n *\n * Animations are skipped when the user prefers reduced motion. Values are read each\n * time an animation starts, so getters can toggle the animation at runtime.\n *\n * @example\n * ```typescript\n * providers: [{ provide: VDND_ANIMATION_CONFIG, useValue: { shiftDuration: 200 } }]\n * ```\n */\nexport const VDND_ANIMATION_CONFIG = new InjectionToken<VdndAnimationConfig>(\n 'VDND_ANIMATION_CONFIG',\n);\n","import { computed, effect, Injectable, signal } from '@angular/core';\nimport { CursorPosition, DraggedItem, DragState, GrabOffset } from '../models/drag-drop.models';\n\n/**\n * Internal state type without high-frequency fields.\n * `cursorPosition`, `keyboardTargetIndex`, `activeDroppableId`, `placeholderId`\n * and `placeholderIndex` are split into dedicated signals so that high-frequency\n * pointer/placeholder updates don't trigger re-evaluation of rarely-changing\n * computeds (or rebuild the core state object every frame).\n */\ntype CoreDragState = Omit<\n DragState,\n | 'cursorPosition'\n | 'keyboardTargetIndex'\n | 'activeDroppableId'\n | 'placeholderId'\n | 'placeholderIndex'\n>;\n\nconst INITIAL_CORE_STATE: CoreDragState = {\n isDragging: false,\n draggedItem: null,\n sourceDroppableId: null,\n sourceIndex: null,\n grabOffset: null,\n initialPosition: null,\n lockAxis: null,\n isKeyboardDrag: false,\n};\n\n/**\n * Central service for managing drag-and-drop state.\n * Uses signals for reactive state management.\n *\n * Architecture: High-frequency fields (`cursorPosition`, `keyboardTargetIndex`,\n * `activeDroppableId`, `placeholderId`, `placeholderIndex`) are stored in dedicated\n * signals, separate from the core state. This prevents 60fps cursor and\n * placeholder updates from rebuilding the core state object or re-evaluating the\n * 8+ computeds that only depend on rarely-changing properties (isDragging,\n * draggedItem, etc.).\n */\n@Injectable({\n providedIn: 'root',\n})\nexport class DragStateService {\n /** Core state signal — contains all rarely-changing properties */\n readonly #state = signal<CoreDragState>(INITIAL_CORE_STATE);\n\n /** High-frequency cursor position — updated at 60fps during pointer drag */\n readonly #cursorPosition = signal<CursorPosition | null>(null);\n\n /** High-frequency keyboard target index — updated on each arrow key press */\n readonly #keyboardTargetIndex = signal<number | null>(null);\n\n /** ID of the droppable currently being hovered over — changes on droppable crossings */\n readonly #activeDroppableId = signal<string | null>(null);\n\n /** `END_OF_LIST` while a droppable is targeted, otherwise null; see placeholderIndex */\n readonly #placeholderId = signal<string | null>(null);\n\n /** Index where the placeholder should be inserted — updated on each placeholder move */\n readonly #placeholderIndex = signal<number | null>(null);\n\n /** Snapshot captured synchronously immediately before the last drag state reset. */\n readonly #endedDragState = signal<DragState | null>(null);\n\n /** Flag indicating if the last drag was cancelled (not dropped) */\n readonly #wasCancelled = signal<boolean>(false);\n\n /** Whether the last drag was cancelled (for droppable to check before emitting drop) */\n readonly wasCancelled = this.#wasCancelled.asReadonly();\n\n /** Snapshot captured synchronously before the last drag reset. */\n readonly endedDragState = this.#endedDragState.asReadonly();\n\n /** Whether a drag operation is in progress */\n readonly isDragging = computed(() => this.#state().isDragging);\n\n /** The currently dragged item, or null */\n readonly draggedItem = computed(() => this.#state().draggedItem);\n\n /** ID of the currently dragged item, or null (convenience signal for filtering) */\n readonly draggedItemId = computed(() => this.#state().draggedItem?.draggableId ?? null);\n\n /** ID of the droppable where the drag started */\n readonly sourceDroppableId = computed(() => this.#state().sourceDroppableId);\n\n /** Original index of the dragged item in the source list */\n readonly sourceIndex = computed(() => this.#state().sourceIndex);\n\n /** ID of the droppable currently being hovered over */\n readonly activeDroppableId = this.#activeDroppableId.asReadonly();\n\n /**\n * `END_OF_LIST` while a droppable is targeted, otherwise null.\n * @deprecated It never identifies an item. Use `placeholderIndex`. Will be removed in the next\n * major version.\n */\n readonly placeholderId = this.#placeholderId.asReadonly();\n\n /** Index where the placeholder should be inserted */\n readonly placeholderIndex = this.#placeholderIndex.asReadonly();\n\n /** Current cursor position */\n readonly cursorPosition = this.#cursorPosition.asReadonly();\n\n /** Offset from cursor to element top-left (for maintaining grab position) */\n readonly grabOffset = computed(() => this.#state().grabOffset);\n\n /** Position when drag started (for axis locking) */\n readonly initialPosition = computed(() => this.#state().initialPosition);\n\n /** Axis to lock movement to */\n readonly lockAxis = computed(() => this.#state().lockAxis);\n\n /** Whether this is a keyboard-initiated drag */\n readonly isKeyboardDrag = computed(() => this.#state().isKeyboardDrag);\n\n /** Target index during keyboard navigation */\n readonly keyboardTargetIndex = this.#keyboardTargetIndex.asReadonly();\n\n constructor() {\n // Inject cursor styles once (for consistent grabbing cursor during drag)\n if (typeof document !== 'undefined') {\n const styleId = 'vdnd-cursor-styles';\n if (!document.getElementById(styleId)) {\n const style = document.createElement('style');\n style.id = styleId;\n style.textContent = `\n body.vdnd-dragging,\n body.vdnd-dragging * {\n cursor: grabbing !important;\n }\n `;\n document.head.appendChild(style);\n }\n }\n\n // Effect to toggle body class during drag\n effect(() => {\n if (typeof document === 'undefined') return;\n const isDragging = this.isDragging();\n document.body.classList.toggle('vdnd-dragging', isDragging);\n });\n }\n\n /**\n * Start a drag operation.\n * `placeholderId` is deprecated with the `placeholderId` signal; the library passes `END_OF_LIST`.\n */\n startDrag(\n item: DraggedItem,\n cursorPosition?: CursorPosition,\n grabOffset?: GrabOffset,\n lockAxis?: 'x' | 'y' | null,\n activeDroppableId?: string | null,\n placeholderId?: string | null,\n placeholderIndex?: number | null,\n sourceIndex?: number | null,\n isKeyboardDrag?: boolean,\n axisLockPosition?: CursorPosition,\n ): void {\n // Reset terminal drag metadata at start of new drag\n this.#endedDragState.set(null);\n this.#wasCancelled.set(false);\n this.#cursorPosition.set(cursorPosition ?? null);\n this.#keyboardTargetIndex.set(isKeyboardDrag ? (sourceIndex ?? 0) : null);\n this.#activeDroppableId.set(activeDroppableId ?? null);\n this.#placeholderId.set(placeholderId ?? null);\n this.#placeholderIndex.set(placeholderIndex ?? null);\n this.#state.set({\n isDragging: true,\n draggedItem: item,\n sourceDroppableId: item.droppableId,\n sourceIndex: sourceIndex ?? null,\n grabOffset: grabOffset ?? null,\n initialPosition: axisLockPosition ?? cursorPosition ?? null,\n lockAxis: lockAxis ?? null,\n isKeyboardDrag: isKeyboardDrag ?? false,\n });\n }\n\n /**\n * Update the drag position and targets.\n * `placeholderId` is deprecated with the `placeholderId` signal; the library passes `END_OF_LIST`.\n */\n updateDragPosition(update: {\n cursorPosition: CursorPosition;\n activeDroppableId: string | null;\n placeholderId: string | null;\n placeholderIndex: number | null;\n }): void {\n if (!this.#state().isDragging) {\n return;\n }\n\n // Write cursor to dedicated high-frequency signal\n this.#cursorPosition.set(update.cursorPosition);\n\n // Each target lives in its own signal, so a placeholder-only frame never\n // rebuilds the core state object or re-fires the rarely-changing computeds.\n // Signals already no-op on identical values, so unconditional sets are safe.\n this.#activeDroppableId.set(update.activeDroppableId);\n this.#placeholderId.set(update.placeholderId);\n this.#placeholderIndex.set(update.placeholderIndex);\n }\n\n /**\n * Update just the active droppable.\n */\n setActiveDroppable(droppableId: string | null): void {\n if (!this.#state().isDragging) {\n return;\n }\n\n this.#activeDroppableId.set(droppableId);\n }\n\n /**\n * Update just the placeholder ID.\n * @deprecated Sets only the deprecated `placeholderId`. Will be removed in the next major\n * version.\n */\n setPlaceholder(placeholderId: string | null): void {\n if (!this.#state().isDragging) {\n return;\n }\n\n this.#placeholderId.set(placeholderId);\n }\n\n /**\n * Update only the placeholder signals without touching cursor position or active droppable.\n *\n * Used by the autoscroll scroll-only fast path: when a scroll fires, the cursor has not\n * moved, so only the placeholder index needs recalculation. Skipping the cursor and\n * active-droppable writes avoids spurious re-evaluation of computeds that read those signals.\n * `placeholderId` is deprecated with the `placeholderId` signal; the library passes `END_OF_LIST`.\n */\n updateScrollOnlyPlaceholder(placeholderId: string | null, placeholderIndex: number | null): void {\n if (!this.#state().isDragging) {\n return;\n }\n\n this.#placeholderId.set(placeholderId);\n this.#placeholderIndex.set(placeholderIndex);\n }\n\n /**\n * End the drag operation and reset state (normal drop).\n */\n endDrag(): void {\n this.#endedDragState.set(this.getStateSnapshot());\n this.#wasCancelled.set(false);\n this.#resetHighFrequencySignals();\n this.#state.set(INITIAL_CORE_STATE);\n }\n\n /**\n * Cancel the drag operation (escape key, disabled, etc.).\n */\n cancelDrag(): void {\n this.#endedDragState.set(this.getStateSnapshot());\n this.#wasCancelled.set(true);\n this.#resetHighFrequencySignals();\n this.#state.set(INITIAL_CORE_STATE);\n }\n\n /**\n * Reset the dedicated high-frequency signals to their initial null state.\n */\n #resetHighFrequencySignals(): void {\n this.#cursorPosition.set(null);\n this.#keyboardTargetIndex.set(null);\n this.#activeDroppableId.set(null);\n this.#placeholderId.set(null);\n this.#placeholderIndex.set(null);\n }\n\n /**\n * Check if a specific droppable is currently active.\n */\n isDroppableActive(droppableId: string): boolean {\n return this.#activeDroppableId() === droppableId;\n }\n\n /**\n * Get the current state snapshot (for event creation).\n */\n getStateSnapshot(): DragState {\n return {\n ...this.#state(),\n activeDroppableId: this.#activeDroppableId(),\n placeholderId: this.#placeholderId(),\n placeholderIndex: this.#placeholderIndex(),\n cursorPosition: this.#cursorPosition(),\n keyboardTargetIndex: this.#keyboardTargetIndex(),\n };\n }\n\n /**\n * Update the keyboard target index (for keyboard drag navigation).\n * Also updates placeholder position to match, applying same-list adjustment.\n */\n setKeyboardTargetIndex(targetIndex: number): void {\n if (!this.#state().isDragging || !this.#state().isKeyboardDrag) {\n return;\n }\n\n const state = this.#state();\n // Same-list adjustment: if target is at or after source, add 1\n // This accounts for the hidden item shifting everything up visually\n const sourceDroppableId = state.draggedItem?.droppableId;\n const activeDroppableId = this.#activeDroppableId();\n const isSameList = sourceDroppableId === activeDroppableId;\n const sourceIndex = state.sourceIndex ?? -1;\n\n let placeholderIndex = targetIndex;\n if (isSameList && sourceIndex >= 0 && targetIndex >= sourceIndex) {\n placeholderIndex = targetIndex + 1;\n }\n\n this.#keyboardTargetIndex.set(targetIndex);\n this.#placeholderIndex.set(placeholderIndex);\n }\n\n /**\n * Update the active droppable during keyboard navigation (for cross-list moves).\n */\n setKeyboardActiveDroppable(droppableId: string | null, targetIndex: number): void {\n if (!this.#state().isDragging || !this.#state().isKeyboardDrag) {\n return;\n }\n\n const state = this.#state();\n // Same-list adjustment: if moving back to source list and target is at or after source, add 1\n const sourceDroppableId = state.draggedItem?.droppableId;\n const isSameList = sourceDroppableId === droppableId;\n const sourceIndex = state.sourceIndex ?? -1;\n\n let placeholderIndex = targetIndex;\n if (isSameList && sourceIndex >= 0 && targetIndex >= sourceIndex) {\n placeholderIndex = targetIndex + 1;\n }\n\n this.#keyboardTargetIndex.set(targetIndex);\n this.#activeDroppableId.set(droppableId);\n this.#placeholderIndex.set(placeholderIndex);\n }\n}\n","/**\n * Query by an exact attribute value without interpolating consumer data into a CSS selector.\n *\n * CSS attribute selectors need string-specific escaping that differs from `CSS.escape()`.\n * Filtering candidates by attribute presence avoids selector syntax errors for IDs containing\n * quotes, brackets, backslashes, or other selector-sensitive characters.\n */\nexport function queryByAttribute<T extends Element>(\n root: ParentNode,\n attributeName: string,\n attributeValue: string,\n): T | null {\n const candidates = root.querySelectorAll<T>(`[${attributeName}]`);\n\n for (const candidate of candidates) {\n if (candidate.getAttribute(attributeName) === attributeValue) {\n return candidate;\n }\n }\n\n return null;\n}\n\nexport function queryAllByAttribute<T extends Element>(\n root: ParentNode,\n attributeName: string,\n attributeValue: string,\n): T[] {\n return Array.from(root.querySelectorAll<T>(`[${attributeName}]`)).filter(\n (candidate) => candidate.getAttribute(attributeName) === attributeValue,\n );\n}\n","import { inject, Injectable, NgZone } from '@angular/core';\nimport { queryAllByAttribute, queryByAttribute } from '../utils/attribute-selectors';\n\n/**\n * Snapshot of the candidate droppables for an active drag session.\n * Rects are cached so per-pointermove hit-testing is pure geometry, avoiding the\n * forced layout flush that `document.elementFromPoint` (plus the pointer-events\n * style write it required) imposed on the hottest drag loop.\n */\ninterface DragSessionSnapshot {\n groupName: string;\n /** Candidate droppables in document order (document order === default paint order). */\n candidates: HTMLElement[];\n /** Cached bounding rects, parallel to `candidates`. */\n rects: DOMRect[];\n /** When true, rects are re-read on the next hit-test (set on scroll/resize). */\n dirty: boolean;\n /**\n * When true, the candidate *list* (not just its rects) is re-queried on the next\n * hit-test. Set when a droppable is added/removed mid-drag so a newly mounted\n * target becomes hit-testable and a removed one stops lingering.\n */\n candidatesStale: boolean;\n /** Bound scroll/resize listener used to mark rects dirty. */\n onViewportChange: () => void;\n /**\n * ResizeObserver watching the candidate droppables so a container-only layout\n * change (which fires no window scroll/resize) still invalidates cached rects.\n * Null when `ResizeObserver` is unavailable (e.g. SSR / jsdom).\n */\n resizeObserver: ResizeObserver | null;\n}\n\n/** The parent lookups stop below `<body>`: it and `<html>` never count as list or item. */\nfunction isPageRoot(element: Element): boolean {\n return element.tagName === 'BODY' || element.tagName === 'HTML';\n}\n\n/**\n * Service for calculating drop positions and finding elements at cursor positions.\n * This is the core algorithm that makes virtual scroll + drag-and-drop work together.\n */\n@Injectable({\n providedIn: 'root',\n})\nexport class PositionCalculatorService {\n readonly #ngZone = inject(NgZone);\n\n /** Data attribute used to identify droppable elements */\n readonly #DROPPABLE_ID_ATTR = 'data-droppable-id';\n\n /** Data attribute used to identify droppable groups */\n readonly #DROPPABLE_GROUP_ATTR = 'data-droppable-group';\n\n /** Data attribute reflecting a droppable's disabled state (present === disabled) */\n readonly #DROPPABLE_DISABLED_ATTR = 'data-droppable-disabled';\n\n /** Data attribute used to identify draggable elements */\n readonly #DRAGGABLE_ID_ATTR = 'data-draggable-id';\n\n /** Reusable result object for getNearEdge (avoids per-frame allocation) */\n readonly #nearEdgeResult = { top: false, bottom: false, left: false, right: false };\n\n /** Active drag session rect snapshot, or null when no drag is in progress. */\n #session: DragSessionSnapshot | null = null;\n\n /**\n * Begin a drag session: snapshot the candidate droppables for `groupName` and\n * their rects once, then watch for viewport changes (scroll/resize) that would\n * invalidate those rects. While a session is active, `findDroppableAtPoint`\n * runs as pure geometry against the cached rects instead of `elementFromPoint`.\n *\n * Safe to call repeatedly — a new call replaces any previous session.\n */\n beginDragSession(groupName: string): void {\n this.endDragSession();\n\n const candidates = this.#queryDroppables(groupName);\n const onViewportChange = () => {\n if (this.#session) {\n this.#session.dirty = true;\n }\n };\n\n this.#session = {\n groupName,\n candidates,\n rects: candidates.map((el) => this.#measureRect(el)),\n dirty: false,\n candidatesStale: false,\n onViewportChange,\n resizeObserver: this.#createResizeObserver(),\n };\n\n // A container-only reflow (an element resize that fires no window scroll/resize)\n // would otherwise leave stale rects — observe the candidates so it marks them dirty.\n this.#observeCandidates(this.#session);\n\n // Capture-phase scroll catches scrolling on any ancestor scroller (scroll does\n // not bubble); resize covers viewport changes. Both only mark rects dirty —\n // the actual re-read is deferred to the next hit-test.\n if (typeof window !== 'undefined') {\n this.#ngZone.runOutsideAngular(() => {\n window.addEventListener('scroll', onViewportChange, { capture: true, passive: true });\n window.addEventListener('resize', onViewportChange, { passive: true });\n });\n }\n }\n\n /**\n * End the current drag session and detach viewport listeners.\n * Safe to call when no session is active.\n */\n endDragSession(): void {\n const session = this.#session;\n if (!session) {\n return;\n }\n this.#session = null;\n session.resizeObserver?.disconnect();\n if (typeof window !== 'undefined') {\n window.removeEventListener('scroll', session.onViewportChange, { capture: true });\n window.removeEventListener('resize', session.onViewportChange);\n }\n }\n\n /**\n * Mark the cached droppable rects as stale so they are re-read on the next\n * hit-test. Called explicitly from the autoscroll recalculation path, where the\n * scroll event has not yet fired but the container has already moved.\n */\n invalidateDroppableRects(): void {\n if (this.#session) {\n this.#session.dirty = true;\n }\n }\n\n /**\n * Re-query the candidate droppable *list* for the active session and re-read their\n * rects. Unlike {@link invalidateDroppableRects} (which only refreshes rects), this\n * picks up droppables added or removed since the snapshot was captured at drag start —\n * the frozen candidate list is otherwise blind to mid-drag mounts/unmounts.\n *\n * Safe to call when no session is active (no-op).\n */\n refreshCandidates(): void {\n const session = this.#session;\n if (!session) {\n return;\n }\n session.candidates = this.#queryDroppables(session.groupName);\n session.rects = session.candidates.map((el) => this.#measureRect(el));\n session.dirty = false;\n session.candidatesStale = false;\n this.#observeCandidates(session);\n }\n\n /**\n * Signal that the set of droppables for `groupName` may have changed (a droppable\n * registered or unregistered mid-drag). Defers the actual re-query to the next\n * hit-test — where a removed element is already gone from the DOM and a newly added\n * one has its data attributes applied — keeping this notification path cheap.\n *\n * Called by {@link DroppableDirective} lifecycle hooks. No-op when the active session\n * belongs to a different group or no session is active.\n */\n notifyCandidatesChanged(groupName: string): void {\n if (this.#session && this.#session.groupName === groupName) {\n this.#session.candidatesStale = true;\n }\n }\n\n /**\n * Find the droppable element at a given point.\n *\n * Uses pure geometric hit-testing against snapshotted droppable rects. When a\n * drag session is active (see {@link beginDragSession}) the rects are cached and\n * reused across frames; otherwise a one-shot DOM query is performed. The\n * `draggedElement` parameter is retained for API compatibility but no longer\n * needs to be hidden — geometry does not depend on cursor occlusion.\n *\n * @param x - Cursor X coordinate\n * @param y - Cursor Y coordinate\n * @param _draggedElement - The element being dragged (unused; kept for compatibility)\n * @param groupName - The drag-and-drop group name to filter by\n * @returns The droppable element, or null if none found\n */\n findDroppableAtPoint(\n x: number,\n y: number,\n _draggedElement: HTMLElement,\n groupName: string,\n ): HTMLElement | null {\n const session = this.#session;\n if (session && session.groupName === groupName) {\n if (session.candidatesStale) {\n // A droppable was added/removed mid-drag: re-query the list (also refreshes rects).\n this.refreshCandidates();\n } else if (session.dirty) {\n for (let i = 0; i < session.candidates.length; i++) {\n session.rects[i] = this.#measureRect(session.candidates[i]);\n }\n session.dirty = false;\n }\n return this.#hitTest(x, y, session.candidates, session.rects);\n }\n\n // No active session: one-shot geometric query (still avoids elementFromPoint).\n const candidates = this.#queryDroppables(groupName);\n const rects = candidates.map((el) => this.#measureRect(el));\n return this.#hitTest(x, y, candidates, rects);\n }\n\n /**\n * Look up a droppable element by its ID.\n *\n * When a drag session is active, searches the cached candidate list (O(n), avoids a DOM\n * query). Falls back to `document.querySelector` when no session is active.\n *\n * Intended for the autoscroll scroll-only fast path, where the active droppable is already\n * known and only the placeholder index needs recalculation.\n */\n getDroppableById(id: string): HTMLElement | null {\n if (this.#session) {\n for (const candidate of this.#session.candidates) {\n if (candidate.getAttribute(this.#DROPPABLE_ID_ATTR) === id) {\n return candidate;\n }\n }\n return null;\n }\n\n if (typeof document === 'undefined') {\n return null;\n }\n return queryByAttribute<HTMLElement>(document, this.#DROPPABLE_ID_ATTR, id);\n }\n\n /**\n * Query all droppable elements belonging to a group, in document order.\n *\n * All group members are included — the disabled check happens per-frame in\n * {@link #hitTest} rather than here, because a droppable can be disabled or\n * re-enabled mid-drag (e.g. a consumer disabling incompatible targets from a\n * `(dragStart)` handler, which fires AFTER the candidate snapshot is captured).\n */\n #queryDroppables(groupName: string): HTMLElement[] {\n if (typeof document === 'undefined') {\n return [];\n }\n return queryAllByAttribute<HTMLElement>(document, this.#DROPPABLE_GROUP_ATTR, groupName);\n }\n\n /**\n * Measure a candidate's hit-test rect, clipped to its nearest `.vdnd-scrollable`\n * ancestor. Without clipping a droppable scrolled mostly out of a clipping container\n * still hit-tests over its full unclipped rect (issue #23 case 3). The intersection is\n * built as a plain DOMRect; an empty intersection yields a negative width/height so the\n * `#hitTest` bounds check can never match it.\n */\n #measureRect(el: HTMLElement): DOMRect {\n const rect = el.getBoundingClientRect();\n const scrollable = el.closest('.vdnd-scrollable');\n if (!scrollable || scrollable === el) {\n return rect;\n }\n\n const clip = scrollable.getBoundingClientRect();\n const top = Math.max(rect.top, clip.top);\n const left = Math.max(rect.left, clip.left);\n const right = Math.min(rect.right, clip.right);\n const bottom = Math.min(rect.bottom, clip.bottom);\n return new DOMRect(left, top, right - left, bottom - top);\n }\n\n /**\n * Create a ResizeObserver (run outside Angular per CLAUDE.md) that marks the session's\n * cached rects dirty when a candidate resizes. Returns null when ResizeObserver is\n * unavailable (SSR / jsdom) so callers degrade gracefully.\n */\n #createResizeObserver(): ResizeObserver | null {\n if (typeof ResizeObserver === 'undefined') {\n return null;\n }\n return this.#ngZone.runOutsideAngular(\n () =>\n new ResizeObserver(() => {\n if (this.#session) {\n this.#session.dirty = true;\n }\n }),\n );\n }\n\n /**\n * Point the session's ResizeObserver at the current candidate list, dropping any\n * previously observed elements. Called on session start and whenever the candidate\n * list is refreshed.\n */\n #observeCandidates(session: DragSessionSnapshot): void {\n const observer = session.resizeObserver;\n if (!observer) {\n return;\n }\n this.#ngZone.runOutsideAngular(() => {\n observer.disconnect();\n for (const candidate of session.candidates) {\n observer.observe(candidate);\n }\n });\n }\n\n /**\n * Whether a droppable element is currently disabled (reflected via the\n * `data-droppable-disabled` attribute by `DroppableDirective`). Read live on each\n * hit-test / navigation step so disabled↔enabled transitions during an active drag\n * take effect immediately. Disabled droppables are excluded from all drag-time\n * candidate sets — pointer hit-testing and keyboard cross-list navigation.\n */\n #isDroppableDisabled(el: HTMLElement): boolean {\n return el.hasAttribute(this.#DROPPABLE_DISABLED_ATTR);\n }\n\n /**\n * Geometric hit-test: return the last candidate (in document order) whose rect\n * contains the point. \"Last in document order\" reproduces the painter's-order\n * tie-break that `elementFromPoint` provided for free — a nested or later\n * overlapping droppable is painted on top of an earlier/ancestor one.\n *\n * Currently-disabled candidates are skipped here (not filtered from the snapshot) so\n * that toggling `disabled` mid-drag takes effect on the very next frame. The check is\n * a cheap `hasAttribute` read that does not force layout, keeping the loop hot.\n */\n #hitTest(x: number, y: number, candidates: HTMLElement[], rects: DOMRect[]): HTMLElement | null {\n let match: HTMLElement | null = null;\n for (let i = 0; i < candidates.length; i++) {\n const candidate = candidates[i];\n if (this.#isDroppableDisabled(candidate)) {\n continue;\n }\n const r = rects[i];\n if (x >= r.left && x <= r.right && y >= r.top && y <= r.bottom) {\n match = candidate;\n }\n }\n return match;\n }\n\n /**\n * Find the draggable element at a given point.\n *\n * @param x - Cursor X coordinate\n * @param y - Cursor Y coordinate\n * @param draggedElement - The element being dragged (will be temporarily hidden)\n * @returns The draggable element, or null if none found\n */\n findDraggableAtPoint(x: number, y: number, draggedElement: HTMLElement): HTMLElement | null {\n const isHidden = draggedElement.offsetParent === null;\n\n let originalPointerEvents: string | undefined;\n if (!isHidden) {\n originalPointerEvents = draggedElement.style.pointerEvents;\n draggedElement.style.pointerEvents = 'none';\n }\n\n try {\n const elementAtPoint = document.elementFromPoint(x, y);\n if (!elementAtPoint) {\n return null;\n }\n\n return this.getDraggableParent(elementAtPoint as HTMLElement);\n } finally {\n if (!isHidden) {\n draggedElement.style.pointerEvents = originalPointerEvents!;\n }\n }\n }\n\n /**\n * Walk up the DOM tree to find a droppable parent element.\n *\n * @param element - Starting element\n * @param groupName - The drag-and-drop group name to filter by\n * @returns The droppable parent element, or null if none found\n */\n getDroppableParent(element: HTMLElement, groupName: string): HTMLElement | null {\n // An empty group name never matches (an empty attribute value is no group)\n if (!groupName) {\n return null;\n }\n\n // Match on the attribute's presence and compare the value here, so the group name needs no\n // selector escaping. Nearer droppables of other groups are skipped.\n const selector = `[${this.#DROPPABLE_GROUP_ATTR}]`;\n let current = element.closest<HTMLElement>(selector);\n while (current && !isPageRoot(current)) {\n if (current.getAttribute(this.#DROPPABLE_GROUP_ATTR) === groupName) {\n return current;\n }\n current = current.parentElement?.closest<HTMLElement>(selector) ?? null;\n }\n\n return null;\n }\n\n /**\n * Walk up the DOM tree to find a draggable parent element.\n *\n * @param element - Starting element\n * @returns The draggable parent element, or null if none found\n */\n getDraggableParent(element: HTMLElement): HTMLElement | null {\n const selector = `[${this.#DRAGGABLE_ID_ATTR}]:not([${this.#DRAGGABLE_ID_ATTR}=\"\"])`;\n const draggable = element.closest<HTMLElement>(selector);\n return draggable && !isPageRoot(draggable) ? draggable : null;\n }\n\n /**\n * Get the draggable ID from an element.\n */\n getDraggableId(element: HTMLElement): string | null {\n return element.getAttribute(this.#DRAGGABLE_ID_ATTR);\n }\n\n /**\n * Get the droppable ID from an element.\n */\n getDroppableId(element: HTMLElement): string | null {\n return element.getAttribute(this.#DROPPABLE_ID_ATTR);\n }\n\n /**\n * Calculate the drop index based on mathematical position.\n *\n * This is an alternative approach that doesn't require the target element\n * to be in the DOM. Useful when the target might be virtualized away.\n *\n * @param scrollTop - Current scroll position of the container\n * @param cursorY - Cursor Y position (viewport-relative)\n * @param containerTop - Top position of the container (viewport-relative)\n * @param itemHeight - Height of each item\n * @param totalItems - Total number of items in the list\n * @returns The calculated drop index\n */\n calculateDropIndex(\n scrollTop: number,\n cursorY: number,\n containerTop: number,\n itemHeight: number,\n totalItems: number,\n ): number {\n // Calculate the position relative to the container's content\n const relativeY = cursorY - containerTop + scrollTop;\n\n // Calculate which item index this corresponds to\n const index = Math.floor(relativeY / itemHeight);\n\n // Clamp to valid range\n return Math.max(0, Math.min(index, totalItems));\n }\n\n /**\n * Check if a point is within a specific threshold of a container's edge.\n *\n * @param position - Current cursor position\n * @param containerRect - Container's bounding rect\n * @param threshold - Distance from edge to trigger (in pixels)\n * @returns Object indicating which edges are near\n */\n getNearEdge(\n position: { x: number; y: number },\n containerRect: DOMRect,\n threshold: number,\n ): { top: boolean; bottom: boolean; left: boolean; right: boolean } {\n this.#nearEdgeResult.top = position.y - containerRect.top <= threshold;\n this.#nearEdgeResult.bottom = containerRect.bottom - position.y <= threshold;\n this.#nearEdgeResult.left = position.x - containerRect.left <= threshold;\n this.#nearEdgeResult.right = containerRect.right - position.x <= threshold;\n return this.#nearEdgeResult;\n }\n\n /**\n * Determine if the cursor is inside a container.\n */\n isInsideContainer(position: { x: number; y: number }, containerRect: DOMRect): boolean {\n return (\n position.x >= containerRect.left &&\n position.x <= containerRect.right &&\n position.y >= containerRect.top &&\n position.y <= containerRect.bottom\n );\n }\n\n /**\n * Find an adjacent droppable in the specified direction (left or right).\n * Used for cross-list keyboard navigation.\n *\n * @param currentDroppableId - The ID of the current droppable\n * @param direction - 'left' or 'right'\n * @param groupName - The drag-and-drop group name\n * @returns Object with droppable info, or null if none found\n */\n findAdjacentDroppable(\n currentDroppableId: string,\n direction: 'left' | 'right',\n groupName: string,\n ): { element: HTMLElement; id: string } | null {\n // Include disabled droppables when establishing left-to-right order and locating the\n // current container — otherwise a container disabled mid-drag (its own index becomes\n // -1) would trap the drag with no reachable neighbour. Disabled droppables are skipped\n // as *targets* during the outward scan below instead.\n const allDroppables = queryAllByAttribute<HTMLElement>(\n document,\n this.#DROPPABLE_GROUP_ATTR,\n groupName,\n );\n\n if (allDroppables.length <= 1) {\n return null;\n }\n\n // Get bounding rects, IDs, and disabled state, sorted by X position\n const droppableInfos: { element: HTMLElement; id: string; rect: DOMRect; disabled: boolean }[] =\n [];\n\n allDroppables.forEach((el) => {\n const htmlEl = el as HTMLElement;\n const id = htmlEl.getAttribute(this.#DROPPABLE_ID_ATTR);\n if (id) {\n droppableInfos.push({\n element: htmlEl,\n id,\n rect: htmlEl.getBoundingClientRect(),\n disabled: this.#isDroppableDisabled(htmlEl),\n });\n }\n });\n\n // Sort by X position (left to right)\n droppableInfos.sort((a, b) => a.rect.left - b.rect.left);\n\n // Find current droppable index (among all, including a now-disabled current container)\n const currentIndex = droppableInfos.findIndex((d) => d.id === currentDroppableId);\n if (currentIndex === -1) {\n return null;\n }\n\n // Scan outward in the requested direction, skipping disabled droppables, until the\n // first enabled neighbour (or run off the end of the list).\n const step = direction === 'left' ? -1 : 1;\n for (let i = currentIndex + step; i >= 0 && i < droppableInfos.length; i += step) {\n const target = droppableInfos[i];\n if (target.disabled) {\n continue;\n }\n return {\n element: target.element,\n id: target.id,\n };\n }\n\n return null;\n }\n\n /**\n * Whether the droppable with the given ID is currently disabled. A droppable that cannot\n * be found is reported as disabled (treat missing as not a valid target). Used to\n * revalidate a keyboard drag's active target at drop time, since it may have been disabled\n * after the drag navigated into it.\n */\n isDroppableDisabledById(id: string): boolean {\n const element = this.getDroppableById(id);\n return element === null || this.#isDroppableDisabled(element);\n }\n}\n","import { inject, Injectable, NgZone } from '@angular/core';\nimport { CursorPosition } from '../models/drag-drop.models';\n\n/**\n * Callback invoked each RAF frame with the latest cursor and a dirty flag.\n *\n * @param cursor — Latest cursor position queued via `queueCursorUpdate()`, or null if none.\n * @param cursorDirty — True when cursor was updated since the previous frame.\n */\nexport type SchedulerTickFn = (cursor: CursorPosition | null, cursorDirty: boolean) => void;\n\n/**\n * Single RAF loop that coordinates all drag-frame work in ordered phases:\n *\n * 1. Participant phase (READ+WRITE): registered participants run first.\n * AutoScrollService registers here to perform edge-scroll + immediate\n * placeholder recalculation in the same synchronous frame — preserving\n * the Safari synchronous-callback constraint.\n * 2. Main compute phase (COMPUTE+WRITE): onTick is called every frame with the\n * latest cursor and a `cursorDirty` flag. Callers skip their hit-test when\n * the flag is false, so autoscroll-only frames (cursor stationary) incur\n * zero hit-test work.\n *\n * PointerDragHandler calls `queueCursorUpdate()` instead of managing its own\n * RAF per pointermove. This coalesces all moves within a frame into one update\n * and ensures pointer-move work always runs after participant work.\n */\n@Injectable({\n providedIn: 'root',\n})\nexport class DragSchedulerService {\n readonly #ngZone = inject(NgZone);\n\n #rafId: number | null = null;\n #onTick: SchedulerTickFn | null = null;\n\n /** Latest cursor queued from pointer move events. */\n #pendingCursor: CursorPosition | null = null;\n /** True when a new cursor was queued since the last frame. */\n #cursorDirty = false;\n\n /** Tick participants called before the main compute phase each frame. */\n readonly #participants: (() => void)[] = [];\n\n /**\n * Start the scheduler RAF loop.\n * No-op if already running.\n */\n start(onTick: SchedulerTickFn): void {\n if (this.#rafId !== null) {\n return;\n }\n this.#onTick = onTick;\n this.#ngZone.runOutsideAngular(() => {\n this.#scheduleNextTick();\n });\n }\n\n /**\n * Stop the scheduler and cancel the pending RAF.\n * Safe to call when not running.\n */\n stop(): void {\n if (this.#rafId !== null) {\n cancelAnimationFrame(this.#rafId);\n this.#rafId = null;\n }\n // Null out onTick so that any in-flight RAF callback (race between cancel\n // and the browser delivering the frame) is a no-op.\n this.#onTick = null;\n this.#pendingCursor = null;\n this.#cursorDirty = false;\n }\n\n /**\n * Queue a cursor update from a pointer move event.\n * Multiple calls between frames are coalesced — only the latest matters.\n */\n queueCursorUpdate(position: CursorPosition): void {\n this.#pendingCursor = position;\n this.#cursorDirty = true;\n }\n\n /**\n * Register a function to be called at the start of each frame, before the main tick.\n * AutoScrollService registers here to perform edge-scroll within the same frame.\n * No-op if the same function reference is already registered.\n */\n addParticipant(fn: () => void): void {\n if (!this.#participants.includes(fn)) {\n this.#participants.push(fn);\n }\n }\n\n /**\n * Unregister a previously added participant.\n * No-op if the function was not registered.\n */\n removeParticipant(fn: () => void): void {\n const idx = this.#participants.indexOf(fn);\n if (idx !== -1) {\n this.#participants.splice(idx, 1);\n }\n }\n\n #scheduleNextTick(): void {\n this.#rafId = requestAnimationFrame(() => this.#tick());\n }\n\n #tick(): void {\n this.#rafId = null;\n\n // Guard against the race where stop() was called but the browser already\n // queued the callback before cancelAnimationFrame() could prevent delivery.\n if (!this.#onTick) {\n return;\n }\n\n // Snapshot and reset dirty flag before participants run so that any cursor\n // update they trigger (theoretically possible in future extensions) is\n // picked up in the NEXT frame, not folded into this one's compute phase.\n const cursorDirty = this.#cursorDirty;\n this.#cursorDirty = false;\n\n // Phase 1 — participants (autoscroll scroll + synchronous placeholder update)\n for (const participant of this.#participants) {\n participant();\n }\n\n // A participant can end the drag (the autoscroll callback may cancel it), which stops\n // the scheduler and clears onTick.\n const onTick = this.#onTick;\n if (!onTick) {\n return;\n }\n\n // Phase 2 — main compute (cursor-based hit-test + signal write)\n onTick(this.#pendingCursor, cursorDirty);\n\n // Reschedule only if still active (stop() may have been called by onTick).\n if (this.#onTick !== null) {\n this.#scheduleNextTick();\n }\n }\n}\n","import { inject, Injectable } from '@angular/core';\nimport { CursorPosition } from '../models/drag-drop.models';\nimport { DragStateService } from './drag-state.service';\nimport { PositionCalculatorService } from './position-calculator.service';\nimport { DragSchedulerService } from './drag-scheduler.service';\n\n/**\n * Configuration for auto-scroll behavior.\n */\nexport interface AutoScrollConfig {\n /** Distance from edge to start scrolling (in pixels) */\n threshold: number;\n /** Maximum scroll speed in pixels per 60fps frame (about 16.67ms) */\n maxSpeed: number;\n /** Whether to accelerate scroll based on distance from edge */\n accelerate: boolean;\n}\n\n/**\n * Default auto-scroll configuration.\n */\nconst DEFAULT_CONFIG: AutoScrollConfig = {\n threshold: 50,\n maxSpeed: 15,\n accelerate: true,\n};\n\nconst BASE_FRAME_DURATION_MS = 1000 / 60;\nconst MIN_SCROLL_FRAME_SCALE = 1;\nconst MAX_SCROLL_FRAME_SCALE = 6;\n\n/**\n * Service that handles auto-scrolling when dragging near container edges.\n */\n@Injectable({\n providedIn: 'root',\n})\nexport class AutoScrollService {\n readonly #dragState = inject(DragStateService);\n readonly #positionCalculator = inject(PositionCalculatorService);\n readonly #scheduler = inject(DragSchedulerService);\n\n /** Currently registered scrollable containers */\n #scrollableContainers = new Map<\n string,\n {\n element: HTMLElement;\n config: AutoScrollConfig;\n }\n >();\n\n /**\n * Candidate containers ordered innermost (deepest in the DOM) first, so a\n * nested scrollable wins over its ancestors under the cursor. Rebuilt lazily\n * whenever registrations change (containers rarely move mid-drag) and once per\n * drag (see startMonitoring), not per frame.\n */\n #orderedContainers:\n | { id: string; element: HTMLElement; config: AutoScrollConfig; depth: number }[]\n | null = null;\n\n /** Bound reference to #participantTick for stable add/remove with the scheduler. */\n readonly #boundParticipantTick: () => void = () => this.#participantTick();\n\n /** Callback to invoke when scrolling occurs (for placeholder recalculation) */\n #onScrollCallback: (() => void) | null = null;\n\n /** Optional cursor position override for edge detection (bypasses DragState read) */\n #cursorOverride: CursorPosition | null = null;\n\n /** Last tick cursor position for stationary detection */\n #lastTickCursorX = NaN;\n #lastTickCursorY = NaN;\n\n /**\n * Last timestamp used to scale per-frame autoscroll distance by elapsed frame time.\n * Scale is intentionally floored at 1 to preserve the existing feel on 60fps+ displays while\n * compensating slower frames that would otherwise under-scroll.\n */\n #lastScrollTimestamp = 0;\n\n /** Reusable direction object for tick loop (avoids per-frame allocation) */\n readonly #tickDirection = { x: 0, y: 0 };\n\n /** Current scroll state */\n readonly #scrollState: {\n containerId: string | null;\n direction: { x: number; y: number };\n speed: number;\n } = {\n containerId: null,\n direction: { x: 0, y: 0 },\n speed: 0,\n };\n\n /**\n * Register a scrollable container for auto-scrolling.\n */\n registerContainer(\n id: string,\n element: HTMLElement,\n config: Partial<AutoScrollConfig> = {},\n ): void {\n this.#scrollableContainers.set(id, {\n element,\n config: { ...DEFAULT_CONFIG, ...config },\n });\n this.#orderedContainers = null;\n }\n\n /**\n * Unregister a scrollable container.\n */\n unregisterContainer(id: string): void {\n this.#scrollableContainers.delete(id);\n this.#orderedContainers = null;\n }\n\n /**\n * Build (or reuse) the candidate list ordered innermost-first by DOM depth.\n *\n * Sorting by absolute DOM depth (descending) is a *total* order, unlike an\n * `element.contains()` comparator which returns 0 for unrelated pairs and so\n * violates transitivity — with ≥3 containers a nested pair separated by an\n * unrelated one in registration order could end up never compared, leaving the\n * ancestor ahead of its descendant. Equal-depth (including unrelated) containers\n * keep registration order via the stable sort, so unrelated lists behave as before.\n */\n #getOrderedContainers(): {\n id: string;\n element: HTMLElement;\n config: AutoScrollConfig;\n depth: number;\n }[] {\n if (this.#orderedContainers) {\n return this.#orderedContainers;\n }\n\n const entries: {\n id: string;\n element: HTMLElement;\n config: AutoScrollConfig;\n depth: number;\n }[] = [];\n for (const [id, { element, config }] of this.#scrollableContainers) {\n // Registration is unconditional (directives can't expose DOM size as a signal, so\n // gating registration on it goes stale — see #27). Filter by live scroll geometry\n // here instead: this list is rebuilt per drag (startMonitoring nulls the cache) and\n // on register/unregister, so a container that grew scrollable after init is picked\n // up on the next drag, and one that shrank stops occupying a candidate slot.\n if (!this.#isScrollable(element)) {\n continue;\n }\n entries.push({ id, element, config, depth: this.#domDepth(element) });\n }\n\n // Deepest first; stable sort keeps registration order on ties.\n entries.sort((a, b) => b.depth - a.depth);\n\n this.#orderedContainers = entries;\n return entries;\n }\n\n /**\n * Whether the element currently has room to scroll on either axis. Read fresh each\n * time the candidate list is (re)built — never cached — so it always reflects the\n * live layout at drag start rather than a stale value captured at registration.\n */\n #isScrollable(element: HTMLElement): boolean {\n return element.scrollHeight > element.clientHeight || element.scrollWidth > element.clientWidth;\n }\n\n /** Number of ancestor elements — the element's absolute depth in the DOM tree. */\n #domDepth(element: HTMLElement): number {\n let depth = 0;\n for (let parent = element.parentElement; parent; parent = parent.parentElement) {\n depth++;\n }\n return depth;\n }\n\n /**\n * Start monitoring for auto-scroll.\n * Registers this service as a tick participant in DragSchedulerService.\n * The scheduler drives the RAF loop; this service handles scroll logic each frame.\n * @param onScroll Optional callback to invoke when scrolling occurs (for placeholder recalculation)\n */\n startMonitoring(onScroll?: () => void): void {\n this.#onScrollCallback = onScroll ?? null;\n // Recompute containment ordering fresh per drag: a registered container may have\n // been reparented (portal/DOM move) since the cache was built, which register/\n // unregister alone wouldn't catch.\n this.#orderedContainers = null;\n this.#scheduler.addParticipant(this.#boundParticipantTick);\n }\n\n /**\n * Stop monitoring for auto-scroll.\n * Removes this service from the scheduler's participant list.\n * Call this when a drag ends.\n */\n stopMonitoring(): void {\n this.#scheduler.removeParticipant(this.#boundParticipantTick);\n this.#onScrollCallback = null;\n this.#cursorOverride = null;\n this.#lastTickCursorX = NaN;\n this.#lastTickCursorY = NaN;\n this.#lastScrollTimestamp = 0;\n this.#scrollState.containerId = null;\n this.#scrollState.direction.x = 0;\n this.#scrollState.direction.y = 0;\n this.#scrollState.speed = 0;\n }\n\n /**\n * Override the cursor position used for edge detection.\n * When set, #tick() uses this instead of DragStateService.cursorPosition().\n * Used by constrainToContainer to provide a position without grabOffset distortion.\n * @internal\n */\n setCursorOverride(position: CursorPosition): void {\n this.#cursorOverride = position;\n }\n\n /**\n * Participant tick — called by DragSchedulerService each RAF frame.\n *\n * Runs the edge-scroll check and, if a scroll is performed, synchronously\n * invokes #onScrollCallback (the placeholder recalculator) in the same frame.\n * No RAF scheduling here — the scheduler owns the loop.\n */\n #participantTick(): void {\n const cursor = this.#cursorOverride ?? this.#dragState.cursorPosition();\n\n // No cursor yet — nothing to scroll toward.\n if (!cursor) {\n return;\n }\n\n // Skip the container iteration when cursor hasn't moved and scroll is idle.\n if (\n cursor.x === this.#lastTickCursorX &&\n cursor.y === this.#lastTickCursorY &&\n !this.isScrolling()\n ) {\n return;\n }\n this.#lastTickCursorX = cursor.x;\n this.#lastTickCursorY = cursor.y;\n\n let scrollPerformed = false;\n // Frame scale is shared across candidates within a tick; computed lazily on\n // the first scroll attempt so stationary/idle frames don't advance the clock.\n let frameScale = 0;\n\n // Candidates are ordered innermost-first: when the deepest container under the\n // cursor is exhausted at its boundary, the loop falls through to its ancestors.\n for (const { id, element, config } of this.#getOrderedContainers()) {\n const rect = element.getBoundingClientRect();\n const isInside = this.#positionCalculator.isInsideContainer(cursor, rect);\n\n if (!isInside) {\n continue;\n }\n\n const nearEdge = this.#positionCalculator.getNearEdge(cursor, rect, config.threshold);\n\n // Reuse the per-frame direction object to avoid allocation.\n const direction = this.#tickDirection;\n direction.x = 0;\n direction.y = 0;\n let maxDistance = 0;\n\n if (nearEdge.top) {\n direction.y = -1;\n maxDistance = Math.max(maxDistance, config.threshold - (cursor.y - rect.top));\n } else if (nearEdge.bottom) {\n direction.y = 1;\n maxDistance = Math.max(maxDistance, config.threshold - (rect.bottom - cursor.y));\n }\n\n if (nearEdge.left) {\n direction.x = -1;\n maxDistance = Math.max(maxDistance, config.threshold - (cursor.x - rect.left));\n } else if (nearEdge.right) {\n direction.x = 1;\n maxDistance = Math.max(maxDistance, config.threshold - (rect.right - cursor.x));\n }\n\n if (direction.x !== 0 || direction.y !== 0) {\n let speed = config.maxSpeed;\n if (config.accelerate) {\n const distanceRatio = maxDistance / config.threshold;\n speed = Math.min(config.maxSpeed, Math.max(1, config.maxSpeed * distanceRatio));\n }\n\n if (frameScale === 0) {\n frameScale = this.#getFrameScale();\n }\n\n // #performScroll reports whether it actually moved the element. Only claim the\n // tick (and stop descending the candidate list) when a scroll really happened —\n // an exhausted container must not block its ancestors from scrolling.\n //\n // Axis independence is per-container: if this container scrolls on *either* axis\n // it claims the whole tick, so a corner where the inner container's Y is exhausted\n // but its X still moves will not additionally apply an ancestor's available Y that\n // same frame. This matches the issue's \"break once a container scrolled\" contract;\n // cross-container axis handoff is intentionally out of scope.\n const scrolled = this.#performScroll(element, direction, frameScale, speed);\n if (scrolled) {\n this.#scrollState.containerId = id;\n this.#scrollState.direction.x = direction.x;\n this.#scrollState.direction.y = direction.y;\n this.#scrollState.speed = speed;\n scrollPerformed = true;\n break;\n }\n }\n }\n\n if (!scrollPerformed) {\n this.#lastScrollTimestamp = 0;\n this.#scrollState.containerId = null;\n this.#scrollState.direction.x = 0;\n this.#scrollState.direction.y = 0;\n this.#scrollState.speed = 0;\n }\n }\n\n /**\n * Perform the actual scroll operation.\n *\n * Each axis is evaluated independently: a boundary-exhausted axis is skipped\n * while the other axis still scrolls (e.g. at a corner where vertical is\n * maxed out but horizontal is available).\n *\n * @returns `true` when at least one axis actually scrolled, `false` when the\n * element was already at its boundary in every requested direction. The\n * caller uses this to fall through to ancestor containers.\n */\n #performScroll(\n element: HTMLElement,\n direction: { x: number; y: number },\n frameScale: number,\n speed: number,\n ): boolean {\n const scrollX = direction.x * speed * frameScale;\n const scrollY = direction.y * speed * frameScale;\n\n // Integer bounds used only as a cheap fast path to skip the assignment.\n // scrollHeight/clientHeight are rounded integers while scrollTop is fractional on\n // WebKit and any non-integer zoom/DPR, so this max can overstate the true one by\n // up to ~1px. It must NOT decide whether a scroll happened — the browser clamps the\n // assignment, so a before/after comparison is the only reliable truth signal.\n // Without it, an element pinned at its fractional max reports `scrolled = true`,\n // permanently claims the tick (blocking ancestor fall-through) and fires the callback\n // every frame against unchanged offsets (the WebKit placeholder-drift family).\n const maxScrollY = element.scrollHeight - element.clientHeight;\n const maxScrollX = element.scrollWidth - element.clientWidth;\n\n let scrolled = false;\n\n // Use direct property assignment for guaranteed synchronous scroll\n // scrollBy() with 'instant' behavior may have async issues in Safari\n if (scrollY !== 0) {\n const canScrollUp = direction.y < 0 && element.scrollTop > 0;\n const canScrollDown = direction.y > 0 && element.scrollTop < maxScrollY;\n if (canScrollUp || canScrollDown) {\n const before = element.scrollTop;\n element.scrollTop += scrollY;\n if (element.scrollTop !== before) {\n scrolled = true;\n }\n }\n }\n\n if (scrollX !== 0) {\n const canScrollLeft = direction.x < 0 && element.scrollLeft > 0;\n const canScrollRight = direction.x > 0 && element.scrollLeft < maxScrollX;\n if (canScrollLeft || canScrollRight) {\n const before = element.scrollLeft;\n element.scrollLeft += scrollX;\n if (element.scrollLeft !== before) {\n scrolled = true;\n }\n }\n }\n\n if (!scrolled) {\n return false;\n }\n\n // Notify callback IMMEDIATELY in the same frame (no RAF delay)\n // Delaying via RAF causes cumulative drift during continuous autoscroll\n // because multiple scrolls happen before each delayed callback runs.\n // Note: No ngZone.run() needed here - the callback (DraggableDirective.#recalculatePlaceholder)\n // already enters the zone when updating drag state.\n this.#onScrollCallback?.();\n\n return true;\n }\n\n #getFrameScale(): number {\n const now = performance.now();\n const elapsedMs =\n this.#lastScrollTimestamp === 0 ? BASE_FRAME_DURATION_MS : now - this.#lastScrollTimestamp;\n\n this.#lastScrollTimestamp = now;\n\n return Math.min(\n Math.max(elapsedMs / BASE_FRAME_DURATION_MS, MIN_SCROLL_FRAME_SCALE),\n MAX_SCROLL_FRAME_SCALE,\n );\n }\n\n /**\n * Check if auto-scrolling is currently active.\n */\n isScrolling(): boolean {\n return (\n this.#scrollState.containerId !== null &&\n (this.#scrollState.direction.x !== 0 || this.#scrollState.direction.y !== 0)\n );\n }\n\n /**\n * Get the current scroll direction.\n */\n getScrollDirection(): { x: number; y: number } {\n return this.#scrollState.direction;\n }\n}\n","import { Injectable } from '@angular/core';\n\n/**\n * Service for cloning DOM elements with their computed styles.\n * Used to create visual copies of dragged elements for the drag preview.\n */\n@Injectable({ providedIn: 'root' })\nexport class ElementCloneService {\n /**\n * CSS properties to copy from source to clone, pre-stored in kebab-case.\n * These are the visual properties that affect appearance. Keeping them\n * kebab-case avoids a camelCase→kebab conversion on every property of every\n * node during the recursive clone walk (a drag-start hot path).\n */\n readonly #stylePropsToCopy: readonly string[] = [\n 'background',\n 'background-color',\n 'background-image',\n 'border',\n 'border-radius',\n 'box-shadow',\n 'color',\n 'font',\n 'font-family',\n 'font-size',\n 'font-weight',\n 'line-height',\n 'padding',\n 'margin',\n 'display',\n 'flex-direction',\n 'align-items',\n 'justify-content',\n 'gap',\n 'text-align',\n 'text-decoration',\n 'width',\n 'height',\n 'min-width',\n 'min-height',\n 'max-width',\n 'max-height',\n 'overflow',\n 'opacity',\n 'transform',\n 'box-sizing',\n ];\n\n /**\n * Clone an element with its computed styles.\n * Returns an HTMLElement ready for use as a drag preview.\n */\n cloneElement(source: HTMLElement): HTMLElement {\n const clone = source.cloneNode(true) as HTMLElement;\n\n // Apply computed styles as inline styles\n this.#applyComputedStyles(source, clone);\n\n // Handle special elements (canvas, video, etc.)\n this.#handleSpecialElements(source, clone);\n\n // Sanitize the clone for safe use as preview\n this.#sanitizeClone(clone);\n\n return clone;\n }\n\n /**\n * Apply computed styles from source to target element.\n * Recursively applies to all child elements.\n */\n #applyComputedStyles(source: HTMLElement, target: HTMLElement): void {\n const computed = window.getComputedStyle(source);\n\n // Copy essential visual properties (keys are already kebab-case)\n for (const prop of this.#stylePropsToCopy) {\n const value = computed.getPropertyValue(prop);\n if (value) {\n target.style.setProperty(prop, value);\n }\n }\n\n // Disable animations and transitions on clone\n target.style.animation = 'none';\n target.style.transition = 'none';\n\n // Recursively apply to children\n const sourceChildren = source.children;\n const targetChildren = target.children;\n\n for (let i = 0; i < sourceChildren.length && i < targetChildren.length; i++) {\n const sourceChild = sourceChildren[i];\n const targetChild = targetChildren[i];\n\n if (sourceChild instanceof HTMLElement && targetChild instanceof HTMLElement) {\n this.#applyComputedStyles(sourceChild, targetChild);\n }\n }\n }\n\n /**\n * Handle special elements that require extra processing.\n */\n #handleSpecialElements(source: HTMLElement, clone: HTMLElement): void {\n // Handle canvas elements - copy current content\n const sourceCanvases = source.querySelectorAll('canvas');\n const cloneCanvases = clone.querySelectorAll('canvas');\n\n sourceCanvases.forEach((srcCanvas, i) => {\n const cloneCanvas = cloneCanvases[i] as HTMLCanvasElement;\n if (cloneCanvas) {\n const ctx = cloneCanvas.getContext('2d');\n if (ctx) {\n cloneCanvas.width = srcCanvas.width;\n cloneCanvas.height = srcCanvas.height;\n ctx.drawImage(srcCanvas, 0, 0);\n }\n }\n });\n\n // Handle video elements - replace with poster or placeholder\n const videos = clone.querySelectorAll('video');\n videos.forEach((video) => {\n const poster = video.poster;\n if (poster) {\n const img = document.createElement('img');\n img.src = poster;\n img.style.width = '100%';\n img.style.height = '100%';\n img.style.objectFit = 'cover';\n video.replaceWith(img);\n } else {\n // Create a placeholder\n const placeholder = document.createElement('div');\n placeholder.style.cssText = `\n width: 100%;\n height: 100%;\n display: flex;\n align-items: center;\n justify-content: center;\n `;\n video.replaceWith(placeholder);\n }\n });\n\n // Handle iframes - replace with placeholder\n const iframes = clone.querySelectorAll('iframe');\n iframes.forEach((iframe) => {\n const placeholder = document.createElement('div');\n const iframeStyles = window.getComputedStyle(iframe);\n placeholder.style.width = iframeStyles.width;\n placeholder.style.height = iframeStyles.height;\n placeholder.style.display = 'flex';\n placeholder.style.alignItems = 'center';\n placeholder.style.justifyContent = 'center';\n iframe.replaceWith(placeholder);\n });\n }\n\n /**\n * Sanitize the clone to prevent interaction issues.\n */\n #sanitizeClone(clone: HTMLElement): void {\n // Remove draggable directive attributes\n clone.removeAttribute('vdndDraggable');\n clone.removeAttribute('data-draggable-id');\n clone.removeAttribute('data-droppable-id');\n\n // Remove Angular-specific attributes\n const angularAttrs = Array.from(clone.attributes).filter(\n (attr) => attr.name.startsWith('ng-') || attr.name.startsWith('_ng'),\n );\n angularAttrs.forEach((attr) => clone.removeAttribute(attr.name));\n\n // Process all descendant elements\n const allElements = clone.querySelectorAll('*');\n allElements.forEach((el) => {\n if (!(el instanceof HTMLElement)) return;\n\n // Remove event-related attributes\n const attrs = Array.from(el.attributes);\n attrs.forEach((attr) => {\n if (\n attr.name.startsWith('on') ||\n attr.name.startsWith('(') ||\n attr.name.startsWith('ng-') ||\n attr.name.startsWith('_ng')\n ) {\n el.removeAttribute(attr.name);\n }\n });\n\n // Remove draggable attributes from children too\n el.removeAttribute('vdndDraggable');\n el.removeAttribute('data-draggable-id');\n el.removeAttribute('data-droppable-id');\n });\n\n // Disable interactive elements\n const interactiveElements = clone.querySelectorAll(\n 'button, input, textarea, select, a, [contenteditable]',\n );\n interactiveElements.forEach((el) => {\n if (el instanceof HTMLElement) {\n el.style.pointerEvents = 'none';\n el.setAttribute('tabindex', '-1');\n el.setAttribute('aria-hidden', 'true');\n el.setAttribute('disabled', 'true');\n }\n });\n\n // A checked radio joins its group as soon as the clone is connected, which unchecks the\n // radio in the source item. Without a name the cloned radios belong to no group.\n clone.querySelectorAll('input[type=\"radio\"][name]').forEach((radio) => {\n radio.removeAttribute('name');\n });\n\n // Remove focus styling classes that might interfere\n clone.classList.remove('vdnd-draggable-dragging');\n clone.classList.remove('vdnd-draggable-disabled');\n }\n}\n","import { computed, inject, Injectable, signal } from '@angular/core';\nimport { DragStateService } from './drag-state.service';\nimport { DraggedItem, END_OF_LIST, GrabOffset } from '../models/drag-drop.models';\n\n/**\n * Service for managing keyboard-initiated drag operations.\n * Works in conjunction with DragStateService to provide keyboard drag functionality.\n */\n@Injectable({\n providedIn: 'root',\n})\nexport class KeyboardDragService {\n readonly #dragState = inject(DragStateService);\n\n /** Total item count for the current droppable (set by droppable on keyboard drag start) */\n readonly #totalItemCount = signal<number>(0);\n\n /** Per-droppable callbacks that scroll the placeholder into view (see `registerRevealer`) */\n readonly #revealers = new Map<string, () => void>();\n\n /** Whether a keyboard drag is currently active */\n readonly isActive = computed(\n () => this.#dragState.isKeyboardDrag() && this.#dragState.isDragging(),\n );\n\n /** Current target index during keyboard navigation */\n readonly targetIndex = computed(() => this.#dragState.keyboardTargetIndex());\n\n /** Source index where the drag started */\n readonly sourceIndex = computed(() => this.#dragState.sourceIndex());\n\n /** Current active droppable ID */\n readonly activeDroppableId = computed(() => this.#dragState.activeDroppableId());\n\n /**\n * Start a keyboard drag operation.\n */\n startKeyboardDrag(\n item: DraggedItem,\n sourceIndex: number,\n totalItemCount: number,\n activeDroppableId: string,\n ): void {\n this.#totalItemCount.set(totalItemCount);\n\n // For keyboard drag, we position the preview at the element's location\n // We use a grab offset of 0,0 since we're not grabbing at a specific point\n const grabOffset: GrabOffset = { x: 0, y: 0 };\n\n // Get the element's position for the cursor position\n // This positions the preview at the element's original location\n const rect = item.element.getBoundingClientRect();\n const cursorPosition = { x: rect.left, y: rect.top };\n\n // Same-list adjustment: at start, targetIndex equals sourceIndex\n // Since sourceIndex >= sourceIndex is always true, add 1 to placeholderIndex\n // This accounts for the hidden item shifting everything up visually\n const initialPlaceholderIndex = sourceIndex + 1;\n\n this.#dragState.startDrag(\n item,\n cursorPosition,\n grabOffset,\n null, // no axis lock for keyboard drag\n activeDroppableId,\n END_OF_LIST,\n initialPlaceholderIndex,\n sourceIndex,\n true, // isKeyboardDrag\n );\n }\n\n /**\n * Move to a specific index during keyboard drag.\n * Returns the clamped target index.\n */\n moveToIndex(targetIndex: number): number {\n if (!this.isActive()) {\n return targetIndex;\n }\n\n const maxIndex = this.#maxTargetIndex(this.activeDroppableId());\n const clampedIndex = Math.max(0, Math.min(targetIndex, maxIndex));\n\n this.#dragState.setKeyboardTargetIndex(clampedIndex);\n this.#revealActivePlaceholder();\n\n return clampedIndex;\n }\n\n /**\n * Move up by one position (ArrowUp).\n * Returns the new target index.\n */\n moveUp(): number {\n const currentTarget = this.targetIndex() ?? 0;\n return this.moveToIndex(currentTarget - 1);\n }\n\n /**\n * Move down by one position (ArrowDown).\n * Returns the new target index.\n */\n moveDown(): number {\n const currentTarget = this.targetIndex() ?? 0;\n return this.moveToIndex(currentTarget + 1);\n }\n\n /**\n * Move to an adjacent droppable (ArrowLeft/ArrowRight).\n * The droppable registry is managed externally.\n */\n moveToDroppable(droppableId: string, targetIndex: number, totalItemCount: number): void {\n if (!this.isActive()) {\n return;\n }\n\n this.#totalItemCount.set(totalItemCount);\n const clampedIndex = Math.max(0, Math.min(targetIndex, this.#maxTargetIndex(droppableId)));\n this.#dragState.setKeyboardActiveDroppable(droppableId, clampedIndex);\n this.#revealActivePlaceholder();\n }\n\n /**\n * Register the callback that scrolls a droppable's placeholder into view. It runs\n * synchronously on every keyboard move into or within that droppable, so a drop that\n * follows before the next render still lands inside the rendered range.\n */\n registerRevealer(droppableId: string, reveal: () => void): void {\n this.#revealers.set(droppableId, reveal);\n }\n\n /**\n * Unregister a droppable's reveal callback. Ignored if another callback has since been\n * registered under the same ID.\n */\n unregisterRevealer(droppableId: string, reveal: () => void): void {\n if (this.#revealers.get(droppableId) === reveal) {\n this.#revealers.delete(droppableId);\n }\n }\n\n /**\n * Complete the keyboard drag (Space or Enter to drop).\n */\n completeKeyboardDrag(): void {\n if (!this.isActive()) {\n return;\n }\n\n this.#dragState.endDrag();\n }\n\n /**\n * Cancel the keyboard drag (Escape).\n */\n cancelKeyboardDrag(): void {\n if (!this.isActive()) {\n return;\n }\n\n this.#dragState.cancelDrag();\n }\n\n /**\n * Update the total item count (when navigating to a new list).\n */\n setTotalItemCount(count: number): void {\n this.#totalItemCount.set(count);\n }\n\n #revealActivePlaceholder(): void {\n const droppableId = this.activeDroppableId();\n if (droppableId !== null) {\n this.#revealers.get(droppableId)?.();\n }\n }\n\n /**\n * Last valid target index in the given droppable. Targets use the drop convention (the item's\n * final index after it leaves its source), so the source list ends at `totalItemCount - 1`,\n * while any other list can be appended to at `totalItemCount`.\n */\n #maxTargetIndex(droppableId: string | null): number {\n const totalItems = this.#totalItemCount();\n const isSourceList =\n droppableId !== null && droppableId === this.#dragState.sourceDroppableId();\n return isSourceList ? Math.max(0, totalItems - 1) : totalItems;\n }\n}\n","import { computed, Injectable, OnDestroy, signal } from '@angular/core';\n\n/**\n * Service that manages a shared overlay container appended to `document.body`.\n *\n * Elements placed inside the overlay container escape any ancestor CSS `transform`,\n * `perspective`, or `filter` that would create a new containing block for\n * `position: fixed` children. This ensures viewport-relative positioning works\n * correctly regardless of where the consuming component sits in the DOM tree.\n *\n * Mirrors the strategy used by Angular CDK's `OverlayContainer`.\n */\n@Injectable({\n providedIn: 'root',\n})\nexport class OverlayContainerService implements OnDestroy {\n #containerElement: HTMLElement | null = null;\n\n /** Number of mounted drag previews currently rendering via a custom template. */\n readonly #templatePreviewCount = signal(0);\n\n /**\n * Whether at least one mounted drag preview renders via a custom template.\n *\n * When true, DraggableDirective/KeyboardDragHandler skip the expensive\n * drag-start element clone: the clone would never be shown because the\n * template takes precedence (see DragPreviewComponent).\n */\n readonly hasTemplatePreview = computed(() => this.#templatePreviewCount() > 0);\n\n /**\n * Register (`active = true`) or unregister (`active = false`) a preview that\n * renders via a custom template. Calls must be balanced per preview instance.\n */\n setTemplatePreviewActive(active: boolean): void {\n this.#templatePreviewCount.update((count) => Math.max(0, count + (active ? 1 : -1)));\n }\n\n /**\n * Returns the shared overlay container element, lazily creating it on first access.\n * Returns `null` in non-browser environments (SSR).\n */\n getContainerElement(): HTMLElement | null {\n if (typeof document === 'undefined') {\n return null;\n }\n\n if (!this.#containerElement) {\n this.#containerElement = document.createElement('div');\n this.#containerElement.classList.add('vdnd-overlay-container');\n document.body.appendChild(this.#containerElement);\n }\n\n return this.#containerElement;\n }\n\n ngOnDestroy(): void {\n this.#containerElement?.remove();\n this.#containerElement = null;\n }\n}\n","import { inject, Injectable } from '@angular/core';\nimport { type CursorPosition, END_OF_LIST, type GrabOffset } from '../models/drag-drop.models';\nimport { PositionCalculatorService } from './position-calculator.service';\nimport type { VirtualScrollStrategy } from '../models/virtual-scroll-strategy';\n\ninterface DroppableCache {\n droppableId: string | null;\n containerType: 'viewport' | 'virtualScroll' | 'virtualContent' | 'fallback';\n scrollContainer: HTMLElement;\n virtualScrollElement: HTMLElement | null;\n virtualContentElement: HTMLElement | null;\n scrollableParent: HTMLElement | null;\n itemHeight: number;\n isConstrainedToContainer: boolean;\n strategy: VirtualScrollStrategy | null;\n}\n\n/** Where a droppable's rows are, relative to the element they scroll in. */\nexport interface DroppableScrollGeometry {\n /** Viewport rect of the element the rows scroll in */\n rect: DOMRect;\n /**\n * How far the rows are scrolled: a row's offset from the first row (as in\n * `VirtualScrollStrategy.getOffsetForIndex`) is `rowTop - rect.top + scrollTop`. Space reserved\n * above the rows (`contentOffset`) is already subtracted.\n */\n scrollTop: number;\n /**\n * Whether the container virtualizes its rows itself (`vdnd-virtual-scroll`,\n * `vdnd-virtual-content`), so a row's index can't be counted from the rows before it. A\n * viewport's rows are virtualized by `*vdndVirtualFor`, which registers a strategy.\n */\n isVirtual: boolean;\n}\n\n@Injectable({\n providedIn: 'root',\n})\nexport class DragIndexCalculatorService {\n readonly #positionCalculator = inject(PositionCalculatorService);\n\n /** Registered strategies by droppable ID */\n readonly #strategies = new Map<string, VirtualScrollStrategy>();\n\n /** Cached droppable metadata to avoid repeated DOM queries during drag */\n readonly #droppableCache = new Map<HTMLElement, DroppableCache>();\n\n /**\n * Register a virtual scroll strategy for a droppable.\n * Used by virtual scroll components to provide dynamic height lookups.\n */\n registerStrategy(droppableId: string, strategy: VirtualScrollStrategy): void {\n this.#strategies.set(droppableId, strategy);\n }\n\n /**\n * Unregister a strategy when the droppable is destroyed.\n */\n unregisterStrategy(droppableId: string): void {\n this.#strategies.delete(droppableId);\n }\n\n /**\n * Get the registered strategy for a droppable ID.\n * Used by draggable to calculate source index with variable heights.\n */\n getStrategyForDroppable(droppableId: string): VirtualScrollStrategy | undefined {\n return this.#strategies.get(droppableId);\n }\n\n clearCache(): void {\n this.#droppableCache.clear();\n }\n\n #resolveDroppable(droppableElement: HTMLElement, draggedItemHeight: number): DroppableCache {\n const cached = this.#droppableCache.get(droppableElement);\n if (cached) return cached;\n\n const isViewport = droppableElement.hasAttribute('data-virtual-viewport');\n const virtualScrollElement = droppableElement.querySelector(\n 'vdnd-virtual-scroll',\n ) as HTMLElement | null;\n const virtualContentElement = (\n droppableElement.matches('vdnd-virtual-content')\n ? droppableElement\n : droppableElement.closest('vdnd-virtual-content')\n ) as HTMLElement | null;\n\n let containerType: DroppableCache['containerType'];\n let scrollContainer: HTMLElement;\n let scrollableParent: HTMLElement | null = null;\n\n if (isViewport) {\n // The viewport scrolls its own rows. Checked first so a list nested in a row is not\n // mistaken for this one.\n containerType = 'viewport';\n scrollContainer = droppableElement;\n } else if (virtualScrollElement) {\n containerType = 'virtualScroll';\n scrollContainer = virtualScrollElement;\n } else if (virtualContentElement) {\n containerType = 'virtualContent';\n scrollableParent = virtualContentElement.closest('.vdnd-scrollable') as HTMLElement | null;\n scrollContainer = scrollableParent ?? virtualContentElement;\n } else {\n containerType = 'fallback';\n scrollContainer = droppableElement;\n }\n\n const droppableId = this.#positionCalculator.getDroppableId(droppableElement);\n const strategy = (droppableId ? this.#strategies.get(droppableId) : null) ?? null;\n\n const configuredHeight =\n virtualScrollElement?.getAttribute('data-item-height') ??\n virtualContentElement?.getAttribute('data-item-height');\n const parsedHeight = configuredHeight ? parseFloat(configuredHeight) : Number.NaN;\n const itemHeight = Number.isFinite(parsedHeight)\n ? parsedHeight\n : this.#getDraggedItemHeightFallback(draggedItemHeight, 50);\n\n const isConstrainedToContainer = droppableElement.hasAttribute('data-constrain-to-container');\n\n const entry: DroppableCache = {\n droppableId,\n containerType,\n scrollContainer,\n virtualScrollElement,\n virtualContentElement,\n scrollableParent,\n itemHeight,\n isConstrainedToContainer,\n strategy,\n };\n\n this.#droppableCache.set(droppableElement, entry);\n return entry;\n }\n\n getTotalItemCount(args: {\n droppableElement: HTMLElement;\n isSameList: boolean;\n draggedItemHeight: number;\n }): number {\n return this.#getTotalItemCount(args.droppableElement, args.isSameList, args.draggedItemHeight);\n }\n\n /**\n * Live scroll geometry of a droppable's rows (see {@link DroppableScrollGeometry}). The same\n * measurement places the placeholder and finds the dragged item's source index.\n */\n getScrollGeometry(\n droppableElement: HTMLElement,\n draggedItemHeight: number,\n ): DroppableScrollGeometry {\n return this.#getScrollGeometry(this.#resolveDroppable(droppableElement, draggedItemHeight));\n }\n\n calculatePlaceholderIndex(args: {\n droppableElement: HTMLElement;\n position: CursorPosition;\n /**\n * Unused: the index probe is direction-independent (capped center + midpoint refinement).\n * Kept so callers don't change.\n */\n previousPosition: CursorPosition | null;\n grabOffset: GrabOffset | null;\n draggedItemHeight: number;\n sourceDroppableId: string | null;\n sourceIndex: number | null;\n }): { index: number; placeholderId: string } {\n const {\n droppableElement,\n position,\n grabOffset,\n draggedItemHeight,\n sourceDroppableId,\n sourceIndex,\n } = args;\n\n // Resolve cached metadata (DOM queries run once per droppable per drag session)\n const cache = this.#resolveDroppable(droppableElement, draggedItemHeight);\n\n // Live reads: getBoundingClientRect() and scrollTop change during scroll\n const { rect, scrollTop: currentScrollTop } = this.#getScrollGeometry(cache);\n\n const {\n strategy,\n itemHeight,\n droppableId: currentDroppableId,\n isConstrainedToContainer,\n } = cache;\n\n // Calculate preview center position mathematically\n // The preview is positioned at: cursorPosition - grabOffset (see drag-preview.component.ts)\n // So preview center = cursorPosition.y - grabOffset.y + previewHeight/2\n // Using math avoids Safari's stale getBoundingClientRect() issue during autoscroll\n // Use actual dragged item height when available (important for dynamic heights)\n const previewHeight = this.#getDraggedItemHeightFallback(draggedItemHeight, itemHeight);\n const previewTopY = position.y - (grabOffset?.y ?? 0);\n const previewBottomY = previewTopY + previewHeight;\n const previewCenterY = previewTopY + previewHeight / 2;\n\n // Capped center probe: use preview center but limit how deep the probe reaches.\n // The cap prevents a tall preview (e.g. 120px among 60px items) from overshooting\n // multiple positions — the center would land 2+ items away, but the cap keeps it\n // within one item of the top edge.\n const indexProbeY = Math.min(previewCenterY, previewTopY + itemHeight / 2);\n\n // Convert to visual index\n const relativeY = indexProbeY - rect.top + currentScrollTop;\n\n // Determine same-list drag info before strategy branch\n const isSameList = sourceDroppableId !== null && sourceDroppableId === currentDroppableId;\n const sourceIndexValue = isSameList ? (sourceIndex ?? -1) : -1;\n\n let visualIndex: number;\n if (strategy) {\n visualIndex = strategy.findIndexAtOffset(relativeY);\n\n // Midpoint refinement for variable heights:\n // Only advance past an item when the preview top has crossed its midpoint.\n // Without this, a short preview entering a tall item's range triggers\n // displacement at ~20% overlap, which looks like unnatural overlapping.\n const topRelativeY = previewTopY - rect.top + currentScrollTop;\n const targetTop = strategy.getOffsetForIndex(visualIndex);\n const targetBottom = strategy.getOffsetForIndex(visualIndex + 1);\n const targetMidpoint = (targetTop + targetBottom) / 2;\n if (topRelativeY >= targetMidpoint) {\n visualIndex += 1;\n }\n } else {\n // Fixed height: simple division\n visualIndex = Math.floor(relativeY / itemHeight);\n }\n\n // Same-list +1 adjustment:\n // - No strategy: always adjust when visual index is at/after source\n // - Strategy: adjust only if exclusion has not been applied yet\n // (prevents an off-by-one window during early drag updates)\n let placeholderIndex = visualIndex;\n if (isSameList && sourceIndexValue >= 0 && visualIndex >= sourceIndexValue) {\n const needsAdjustment = !strategy || !this.#isSourceIndexExcluded(strategy, sourceIndexValue);\n if (needsAdjustment) {\n placeholderIndex = visualIndex + 1;\n }\n }\n\n // Get total items using cached strategy to avoid duplicate DOM queries\n let totalItems: number;\n const cachedItemCount = strategy?.getItemCount();\n if (cachedItemCount !== undefined && Number.isFinite(cachedItemCount)) {\n totalItems = Math.max(0, cachedItemCount);\n } else {\n totalItems = this.#getTotalItemCount(droppableElement, isSameList, draggedItemHeight);\n }\n\n // Edge detection: allow dropping at the END of the list when cursor is near bottom edge.\n // Due to max scroll limits, the math alone can't reach totalItems when the list is longer\n // than the viewport. If cursor is in the bottom portion of the container and we're at\n // or past the last visible slot, snap to totalItems.\n const cursorRelativeToBottom = rect.bottom - previewCenterY;\n const isNearBottomEdge = cursorRelativeToBottom < itemHeight;\n if (isNearBottomEdge && placeholderIndex >= totalItems - 1) {\n placeholderIndex = totalItems;\n }\n\n // When the preview is constrained to the container bounds, large dragged items can\n // cover the first/last slots while their center never reaches them. Snap to edges\n // using preview bounds so top/bottom drops remain reachable.\n if (isConstrainedToContainer) {\n const droppableRect = droppableElement.getBoundingClientRect();\n const edgeTolerance = 2;\n const distanceToTop = Math.abs(previewTopY - droppableRect.top);\n const distanceToBottom = Math.abs(droppableRect.bottom - previewBottomY);\n\n if (distanceToTop <= edgeTolerance && distanceToTop <= distanceToBottom) {\n placeholderIndex = 0;\n } else if (distanceToBottom <= edgeTolerance) {\n placeholderIndex = totalItems;\n }\n }\n\n // Clamp to valid range\n placeholderIndex = Math.max(0, Math.min(placeholderIndex, totalItems));\n\n return { index: placeholderIndex, placeholderId: END_OF_LIST };\n }\n\n #getScrollGeometry(cache: DroppableCache): DroppableScrollGeometry {\n const { containerType, scrollContainer } = cache;\n const rect = scrollContainer.getBoundingClientRect();\n const isVirtual = containerType === 'virtualScroll' || containerType === 'virtualContent';\n\n switch (containerType) {\n case 'viewport':\n return {\n rect,\n scrollTop: scrollContainer.scrollTop - this.#readContentOffset(scrollContainer),\n isVirtual,\n };\n case 'virtualContent':\n // Without a vdndScrollable parent the content element itself is measured, unscrolled\n return cache.scrollableParent\n ? {\n rect,\n scrollTop:\n scrollContainer.scrollTop - this.#readContentOffset(cache.virtualContentElement),\n isVirtual,\n }\n : { rect, scrollTop: 0, isVirtual };\n default:\n return { rect, scrollTop: scrollContainer.scrollTop, isVirtual };\n }\n }\n\n /** The `data-content-offset` (px reserved above the rows) of a virtual container, or 0. */\n #readContentOffset(element: HTMLElement | null): number {\n const offset = parseFloat(element?.getAttribute('data-content-offset') ?? '');\n return Number.isFinite(offset) ? offset : 0;\n }\n\n #getTotalItemCount(\n droppableElement: HTMLElement,\n isSameList: boolean,\n draggedItemHeight: number,\n ): number {\n // Check if a registered strategy exists\n const droppableId = this.#positionCalculator.getDroppableId(droppableElement);\n const strategy = droppableId ? this.#strategies.get(droppableId) : null;\n const strategyItemCount = strategy?.getItemCount();\n if (strategyItemCount !== undefined && Number.isFinite(strategyItemCount)) {\n return Math.max(0, strategyItemCount);\n }\n\n // Check for embedded virtual scroll component\n const virtualScroll = droppableElement.querySelector('vdnd-virtual-scroll');\n if (virtualScroll) {\n // Use data-total-items attribute if available (always the true N)\n const totalItemsAttr = virtualScroll.getAttribute('data-total-items');\n if (totalItemsAttr) {\n const count = parseInt(totalItemsAttr, 10);\n if (Number.isFinite(count)) {\n return count;\n }\n }\n\n // Fallback: Use the spacer's height, NOT scrollHeight, to determine item count.\n // scrollHeight can be inflated by absolutely-positioned elements like the placeholder.\n const spacer = virtualScroll.querySelector(\n '.vdnd-virtual-scroll-spacer',\n ) as HTMLElement | null;\n const configuredHeight = virtualScroll.getAttribute('data-item-height');\n const itemHeight = configuredHeight\n ? parseInt(configuredHeight, 10)\n : this.#getDraggedItemHeightFallback(draggedItemHeight, 50);\n\n let totalHeight: number;\n if (spacer) {\n // Get the spacer's explicit height (set via Angular binding)\n totalHeight = parseFloat(spacer.style.height) || 0;\n } else {\n // Fallback: use scrollHeight if spacer not found\n totalHeight = (virtualScroll as HTMLElement).scrollHeight;\n }\n\n // When strategy exists, spacer height already accounts for exclusion.\n // Don't apply same-list +1 adjustment — strategy handles it.\n if (strategy) {\n const count = Math.round(totalHeight / itemHeight);\n return count;\n }\n\n // Spacer height reflects full N items (getTotalHeight no longer excludes)\n const count = Math.floor(totalHeight / itemHeight);\n return count;\n }\n\n // Check for page-level scroll (vdnd-virtual-content)\n const virtualContent = droppableElement.matches('vdnd-virtual-content')\n ? droppableElement\n : droppableElement.closest('vdnd-virtual-content');\n if (virtualContent) {\n // Prefer explicit total items attribute (works for both fixed and dynamic heights)\n const totalItemsAttr = (virtualContent as HTMLElement).getAttribute('data-total-items');\n if (totalItemsAttr) {\n const count = parseInt(totalItemsAttr, 10);\n if (Number.isFinite(count)) {\n // data-total-items is the true total N (derived from strategy item count)\n return count;\n }\n }\n\n // Fallback: use spacer height to determine total items\n const spacer = virtualContent.querySelector('.vdnd-content-spacer') as HTMLElement | null;\n if (spacer) {\n const totalHeight = parseFloat(spacer.style.height) || 0;\n const configuredHeight = virtualContent.getAttribute('data-item-height');\n const itemHeight = configuredHeight\n ? parseInt(configuredHeight, 10)\n : this.#getDraggedItemHeightFallback(draggedItemHeight, 72);\n return Math.floor(totalHeight / itemHeight);\n }\n }\n\n // Fallback for non-virtual scroll — querySelectorAll finds all N items\n // (including the hidden dragged item), so no adjustment needed\n const items = droppableElement.querySelectorAll('[data-draggable-id]');\n return items.length;\n }\n\n #getDraggedItemHeightFallback(height: number, fallback: number): number {\n return Number.isFinite(height) && height > 0 ? height : fallback;\n }\n\n /**\n * Detect whether a strategy has already excluded the source index.\n *\n * With exclusion applied, the source slot collapses in visual space:\n * offset(sourceIndex + 1) <= offset(sourceIndex). Without exclusion,\n * the next offset is strictly greater.\n */\n #isSourceIndexExcluded(strategy: VirtualScrollStrategy, sourceIndex: number): boolean {\n if (sourceIndex < 0) {\n return false;\n }\n\n const sourceOffset = strategy.getOffsetForIndex(sourceIndex);\n const nextOffset = strategy.getOffsetForIndex(sourceIndex + 1);\n\n return nextOffset <= sourceOffset;\n }\n}\n","import { ChangeDetectionStrategy, Component, input } from '@angular/core';\n\n/**\n * Renders an empty placeholder that takes up space in the document flow.\n *\n * This component is used internally by virtual scroll containers to show\n * where an item will be dropped. It's rendered inline with items and\n * takes up the same vertical space as an item.\n *\n * The placeholder is just empty space - no borders, no background.\n * Consumers can style it via CSS if desired.\n */\n@Component({\n selector: 'vdnd-drag-placeholder',\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n class: 'vdnd-drag-placeholder vdnd-drag-placeholder-visible',\n '[style.height.px]': 'itemHeight()',\n },\n styles: `\n :host {\n display: block;\n pointer-events: none;\n }\n `,\n template: ``,\n})\nexport class DragPlaceholderComponent {\n /** Item height for sizing */\n itemHeight = input.required<number>();\n}\n","import { NgZone, type WritableSignal } from '@angular/core';\n\n/** A layout value, or 0 where there is no layout (server rendering leaves them undefined). */\nfunction layoutValue(value: number): number {\n return Number.isFinite(value) ? value : 0;\n}\n\nexport function bindRafThrottledScrollTopSignal(options: {\n element: HTMLElement;\n ngZone: NgZone;\n scrollTop: WritableSignal<number>;\n thresholdPx?: number;\n onCommit?: (scrollTop: number) => void;\n}): () => void {\n const { element, ngZone, scrollTop, thresholdPx = 5, onCommit } = options;\n\n let pendingRaf: number | null = null;\n let lastCommittedScrollTop = layoutValue(element.scrollTop);\n\n const onScroll = () => {\n if (pendingRaf !== null) {\n return;\n }\n\n const currentScrollTop = element.scrollTop;\n if (Math.abs(currentScrollTop - lastCommittedScrollTop) < thresholdPx) {\n return;\n }\n\n pendingRaf = requestAnimationFrame(() => {\n pendingRaf = null;\n const finalScrollTop = element.scrollTop;\n if (Math.abs(finalScrollTop - lastCommittedScrollTop) >= thresholdPx) {\n lastCommittedScrollTop = finalScrollTop;\n scrollTop.set(finalScrollTop);\n onCommit?.(finalScrollTop);\n }\n });\n };\n\n ngZone.runOutsideAngular(() => {\n element.addEventListener('scroll', onScroll, { passive: true });\n });\n\n scrollTop.set(lastCommittedScrollTop);\n\n return () => {\n if (pendingRaf !== null) {\n cancelAnimationFrame(pendingRaf);\n pendingRaf = null;\n }\n element.removeEventListener('scroll', onScroll);\n };\n}\n\nexport function bindResizeObserverHeightSignal(options: {\n element: HTMLElement;\n ngZone: NgZone;\n height: WritableSignal<number>;\n minDeltaPx?: number;\n}): () => void {\n const { element, ngZone, height, minDeltaPx = 1 } = options;\n\n if (typeof ResizeObserver === 'undefined') {\n height.set(layoutValue(element.clientHeight));\n return () => undefined;\n }\n\n let observer: ResizeObserver | null = null;\n\n ngZone.runOutsideAngular(() => {\n observer = new ResizeObserver((entries) => {\n for (const entry of entries) {\n const nextHeight = entry.contentRect.height;\n if (Math.abs(nextHeight - height()) > minDeltaPx) {\n height.set(nextHeight);\n }\n }\n });\n observer.observe(element);\n });\n\n height.set(layoutValue(element.clientHeight));\n\n return () => {\n observer?.disconnect();\n observer = null;\n };\n}\n","import { DestroyRef, effect, inject } from '@angular/core';\nimport { type AutoScrollConfig, AutoScrollService } from '../services/auto-scroll.service';\n\ninterface AutoScrollRegistrationOptions {\n autoScrollService: AutoScrollService;\n getElement: () => HTMLElement;\n getId: () => string;\n enabled: () => boolean;\n config: () => Partial<AutoScrollConfig>;\n canRegister?: () => boolean;\n}\n\nexport function createAutoScrollRegistration(options: AutoScrollRegistrationOptions): void {\n const destroyRef = inject(DestroyRef);\n let registeredId: string | null = null;\n\n const unregisterCurrent = (): void => {\n if (registeredId === null) {\n return;\n }\n\n options.autoScrollService.unregisterContainer(registeredId);\n registeredId = null;\n };\n\n effect(() => {\n const enabled = options.enabled();\n const id = options.getId();\n const config = options.config();\n const canRegister = options.canRegister?.() ?? true;\n\n if (!enabled || !canRegister) {\n unregisterCurrent();\n return;\n }\n\n if (registeredId !== null && registeredId !== id) {\n unregisterCurrent();\n }\n\n options.autoScrollService.registerContainer(id, options.getElement(), config);\n registeredId = id;\n });\n\n destroyRef.onDestroy(unregisterCurrent);\n}\n","import { afterNextRender, Injector } from '@angular/core';\nimport {\n DEFAULT_SHIFT_DURATION,\n DEFAULT_SHIFT_EASING,\n type VdndAnimationConfig,\n} from '../tokens/animation-config.token';\n\n/** A rendered element and the identity it currently represents (trackBy key). */\nexport type ShiftAnimationEntry = readonly [key: unknown, element: HTMLElement];\n\ninterface MeasuredPosition {\n key: unknown;\n x: number;\n y: number;\n}\n\ninterface RunningShift {\n animation: Animation;\n /** Starting offset of the animation (it eases from here to 0) */\n x: number;\n y: number;\n}\n\n/** Layout changes smaller than this are ignored (sub-pixel rounding noise). */\nconst MIN_SHIFT_PX = 0.5;\n\n/**\n * FLIP animator for items displaced by the drag placeholder.\n *\n * Call `beforeUpdate()` before the DOM reflects a new drag/placeholder state. When the\n * placeholder moved (or the drag ended), it snapshots every rendered element's visual position, then after\n * the render measures again and plays a compositor-only `transform` animation from the\n * old position to the new one.\n *\n * Positions are measured relative to the scroll content, so scrolling (including\n * programmatic scroll in the same tick) never animates. Measurements include any\n * in-flight animation, so a new displacement retargets from where the item currently\n * is instead of stacking or jumping. Elements whose target did not change keep their\n * running animation untouched.\n * @internal\n */\nexport class ShiftAnimator {\n readonly #config: VdndAnimationConfig;\n readonly #injector: Injector;\n readonly #getScrollElement: () => HTMLElement | null;\n readonly #getEntries: () => Iterable<ShiftAnimationEntry>;\n\n readonly #running = new Map<HTMLElement, RunningShift>();\n #snapshot: Map<HTMLElement, MeasuredPosition> | null = null;\n #reducedMotionQuery: MediaQueryList | null | undefined;\n #wasDragging = false;\n #lastPlaceholderIndex = -1;\n\n constructor(options: {\n config: VdndAnimationConfig;\n injector: Injector;\n getScrollElement: () => HTMLElement | null;\n getEntries: () => Iterable<ShiftAnimationEntry>;\n }) {\n this.#config = options.config;\n this.#injector = options.injector;\n this.#getScrollElement = options.getScrollElement;\n this.#getEntries = options.getEntries;\n }\n\n /**\n * Notify the animator of the drag state about to be rendered.\n * @param placeholderIndex placeholder index in this list, or -1 when not shown here\n */\n beforeUpdate(isDragging: boolean, placeholderIndex: number): void {\n const wasDragging = this.#wasDragging;\n const previousIndex = this.#lastPlaceholderIndex;\n this.#wasDragging = isDragging;\n this.#lastPlaceholderIndex = placeholderIndex;\n\n if (!isDragging) {\n // Drop/cancel: one last pass slides rows from their drag layout into the committed\n // order. After a drop the rows usually already sit in their final slots, so in-flight\n // slides simply finish; after a cancel the displaced rows slide back.\n // A pending snapshot already holds this tick's \"before\".\n if (!wasDragging || this.#snapshot) {\n return;\n }\n if (!this.#isEnabled()) {\n this.cancelAll();\n return;\n }\n this.#snapshot = this.#measure();\n afterNextRender(() => this.#play(), { injector: this.#injector });\n return;\n }\n\n // Drag start renders the placeholder in the hidden item's slot — nothing moves.\n // A pending snapshot means another update already captured this tick's \"before\".\n if (!wasDragging || placeholderIndex === previousIndex || this.#snapshot) {\n return;\n }\n if (!this.#isEnabled()) {\n return;\n }\n\n this.#snapshot = this.#measure();\n afterNextRender(() => this.#play(), { injector: this.#injector });\n }\n\n /** Stop the shift animation on an element (e.g. before its view is recycled). */\n cancel(element: HTMLElement): void {\n const running = this.#running.get(element);\n if (!running) return;\n this.#running.delete(element);\n running.animation.cancel();\n }\n\n /** Stop every running shift animation. */\n cancelAll(): void {\n for (const running of this.#running.values()) {\n running.animation.cancel();\n }\n this.#running.clear();\n }\n\n #isEnabled(): boolean {\n if (this.#duration() <= 0) return false;\n if (typeof Element === 'undefined' || typeof Element.prototype.animate !== 'function') {\n return false;\n }\n return !this.#prefersReducedMotion();\n }\n\n #duration(): number {\n return this.#config.shiftDuration ?? DEFAULT_SHIFT_DURATION;\n }\n\n #prefersReducedMotion(): boolean {\n if (this.#reducedMotionQuery === undefined) {\n this.#reducedMotionQuery =\n typeof matchMedia === 'function' ? matchMedia('(prefers-reduced-motion: reduce)') : null;\n }\n return this.#reducedMotionQuery?.matches ?? false;\n }\n\n /** Scroll-content origin, so positions are independent of the scroll offset. */\n #origin(): { x: number; y: number } {\n const scrollElement = this.#getScrollElement();\n if (!scrollElement) return { x: 0, y: 0 };\n const rect = scrollElement.getBoundingClientRect();\n return { x: rect.left - scrollElement.scrollLeft, y: rect.top - scrollElement.scrollTop };\n }\n\n #measure(): Map<HTMLElement, MeasuredPosition> {\n const origin = this.#origin();\n const positions = new Map<HTMLElement, MeasuredPosition>();\n for (const [key, element] of this.#getEntries()) {\n const rect = element.getBoundingClientRect();\n // Hidden (display: none) elements, such as the dragged item, have no box.\n if (rect.width === 0 && rect.height === 0) continue;\n positions.set(element, { key, x: rect.left - origin.x, y: rect.top - origin.y });\n }\n return positions;\n }\n\n #play(): void {\n const first = this.#snapshot;\n this.#snapshot = null;\n if (!first) return;\n\n const last = this.#measure();\n const stale: HTMLElement[] = [];\n const shifts: { element: HTMLElement; x: number; y: number }[] = [];\n\n // Read phase — no writes until every element is measured.\n for (const [element, to] of last) {\n const from = first.get(element);\n if (!from || !Object.is(from.key, to.key)) {\n // Newly rendered or recycled for another item: must not animate from a stale offset.\n stale.push(element);\n continue;\n }\n\n const dx = from.x - to.x;\n const dy = from.y - to.y;\n if (Math.abs(dx) < MIN_SHIFT_PX && Math.abs(dy) < MIN_SHIFT_PX) {\n continue;\n }\n\n // Both measurements include the in-flight offset, so the new animation must\n // start from that offset plus the layout delta to continue from the current spot.\n const current = this.#currentOffset(element);\n shifts.push({ element, x: dx + current.x, y: dy + current.y });\n }\n\n // Write phase\n for (const element of stale) {\n this.cancel(element);\n }\n for (const shift of shifts) {\n this.#start(shift.element, shift.x, shift.y);\n }\n }\n\n #currentOffset(element: HTMLElement): { x: number; y: number } {\n const running = this.#running.get(element);\n // Effect-level easing makes `progress` the eased progress, i.e. the fraction travelled.\n const progress = running?.animation.effect?.getComputedTiming().progress;\n if (!running || progress === null || progress === undefined) {\n return { x: 0, y: 0 };\n }\n const remaining = 1 - progress;\n return { x: running.x * remaining, y: running.y * remaining };\n }\n\n #start(element: HTMLElement, x: number, y: number): void {\n this.#running.get(element)?.animation.cancel();\n\n const animation = element.animate(\n [{ transform: `translate(${x}px, ${y}px)` }, { transform: 'translate(0px, 0px)' }],\n {\n duration: this.#duration(),\n easing: this.#config.shiftEasing ?? DEFAULT_SHIFT_EASING,\n // Layer on top of any transform the consumer already applies to the item.\n composite: 'add',\n },\n );\n this.#running.set(element, { animation, x, y });\n animation.onfinish = () => {\n if (this.#running.get(element)?.animation === animation) {\n this.#running.delete(element);\n }\n };\n }\n}\n","import {\n afterNextRender,\n afterRenderEffect,\n AfterViewInit,\n ChangeDetectionStrategy,\n Component,\n computed,\n effect,\n ElementRef,\n inject,\n Injector,\n input,\n NgZone,\n OnDestroy,\n OnInit,\n PLATFORM_ID,\n signal,\n TemplateRef,\n untracked,\n} from '@angular/core';\nimport { isPlatformBrowser, NgTemplateOutlet } from '@angular/common';\nimport { DragStateService } from '../services/drag-state.service';\nimport { AutoScrollConfig, AutoScrollService } from '../services/auto-scroll.service';\nimport { KeyboardDragService } from '../services/keyboard-drag.service';\nimport { DragIndexCalculatorService } from '../services/drag-index-calculator.service';\nimport { DragPlaceholderComponent } from './drag-placeholder.component';\nimport {\n bindRafThrottledScrollTopSignal,\n bindResizeObserverHeightSignal,\n} from '../utils/dom-signal-bindings';\nimport { createAutoScrollRegistration } from '../utils/auto-scroll-registration';\nimport type { VirtualScrollStrategy } from '../models/virtual-scroll-strategy';\nimport { FixedHeightStrategy } from '../strategies/fixed-height.strategy';\nimport { DynamicHeightStrategy } from '../strategies/dynamic-height.strategy';\nimport { queryByAttribute } from '../utils/attribute-selectors';\nimport { VDND_ANIMATION_CONFIG } from '../tokens/animation-config.token';\nimport { ShiftAnimationEntry, ShiftAnimator } from '../utils/shift-animator';\n\n/**\n * Context provided to the item template.\n */\nexport interface VirtualScrollItemContext<T> {\n /** The item data */\n $implicit: T;\n /** The item's index in the original array */\n index: number;\n /** Whether this item is \"sticky\" (always rendered) */\n isSticky: boolean;\n}\n\n/**\n * A virtual scroll container that only renders visible items.\n *\n * Key features:\n * - Only renders items within the visible viewport plus an overscan buffer\n * - Supports \"sticky\" items that are always rendered (used for dragged items)\n * - Uses spacer divs to maintain correct scroll height\n * - Integrates with the drag-and-drop system\n * - Automatic height detection via ResizeObserver when containerHeight is not provided\n * - Supports dynamic item heights via `dynamicItemHeight` input\n *\n * @example\n * ```html\n * <!-- With fixed height items -->\n * <vdnd-virtual-scroll\n * [items]=\"items()\"\n * [itemHeight]=\"50\"\n * [containerHeight]=\"400\"\n * [trackByFn]=\"trackById\">\n * <ng-template let-item let-index=\"index\">\n * <div class=\"item\">{{ item.name }}</div>\n * </ng-template>\n * </vdnd-virtual-scroll>\n *\n * <!-- With dynamic height items -->\n * <vdnd-virtual-scroll\n * [items]=\"items()\"\n * [itemHeight]=\"50\"\n * [dynamicItemHeight]=\"true\"\n * [containerHeight]=\"400\"\n * [trackByFn]=\"trackById\">\n * <ng-template let-item let-index=\"index\">\n * <div class=\"item\">{{ item.description }}</div>\n * </ng-template>\n * </vdnd-virtual-scroll>\n * ```\n */\n@Component({\n selector: 'vdnd-virtual-scroll',\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [NgTemplateOutlet, DragPlaceholderComponent],\n host: {\n class: 'vdnd-virtual-scroll',\n '[style.height.px]': 'containerHeight() ?? null',\n '[attr.data-item-height]': 'itemHeight()',\n '[attr.data-total-items]': 'items().length',\n },\n template: `\n <!-- Single spacer maintains scroll height -->\n <div class=\"vdnd-virtual-scroll-spacer\" [style.height.px]=\"totalHeight()\"></div>\n\n <!-- Content wrapper positioned via GPU-accelerated transform -->\n <div class=\"vdnd-virtual-scroll-content-wrapper\" [style.transform]=\"contentTransform()\">\n @for (entry of renderedItems(); track trackEntry($index, entry)) {\n @if (entry.type === 'placeholder') {\n <vdnd-drag-placeholder [itemHeight]=\"placeholderHeight()\" />\n } @else {\n <ng-container\n *ngTemplateOutlet=\"\n itemTemplate();\n context: {\n $implicit: entry.data,\n index: entry.index,\n isSticky: entry.isSticky,\n }\n \"\n >\n </ng-container>\n }\n }\n </div>\n `,\n styles: `\n :host {\n display: block;\n overflow: auto;\n position: relative;\n /* Disable browser scroll anchoring - this prevents scroll position from being\n adjusted when the DOM changes (e.g., when placeholder position updates).\n Without this, autoscroll UP would fight with browser's scroll restoration. */\n overflow-anchor: none;\n }\n\n .vdnd-virtual-scroll-spacer {\n /* Invisible spacer that maintains scroll height */\n position: absolute;\n top: 0;\n left: 0;\n width: 1px;\n visibility: hidden;\n pointer-events: none;\n }\n\n .vdnd-virtual-scroll-content-wrapper {\n /* GPU-accelerated positioning */\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n will-change: transform;\n }\n `,\n})\nexport class VirtualScrollContainerComponent<T> implements OnInit, AfterViewInit, OnDestroy {\n readonly #dragState = inject(DragStateService);\n readonly #elementRef = inject(ElementRef<HTMLElement>);\n readonly #autoScrollService = inject(AutoScrollService);\n readonly #dragIndexCalculator = inject(DragIndexCalculatorService);\n readonly #keyboardDrag = inject(KeyboardDragService);\n readonly #ngZone = inject(NgZone);\n readonly #injector = inject(Injector);\n readonly #isBrowser = isPlatformBrowser(inject(PLATFORM_ID));\n\n /** Cleanup function for scroll listener */\n #scrollCleanup: (() => void) | null = null;\n #resizeCleanup: (() => void) | null = null;\n\n /** ResizeObserver for dynamic height measurement (only in dynamic height mode) */\n readonly #itemResizeObserver = signal<ResizeObserver | null>(null);\n\n /** Map from observed HTMLElement to its trackBy key */\n readonly #observedElements = new WeakMap<HTMLElement, unknown>();\n /** Stable mapping from rendered key to observed element for unobserve cleanup */\n readonly #observedElementByKey = new Map<unknown, HTMLElement>();\n\n /** Measured height from ResizeObserver (used when containerHeight is not provided) */\n readonly #measuredHeight = signal(0);\n\n /** Slides items displaced by the placeholder (only when VDND_ANIMATION_CONFIG is provided) */\n readonly #shiftAnimator = this.#createShiftAnimator();\n\n /** Template for rendering each item - passed as input instead of content child for reliability */\n itemTemplate = input.required<TemplateRef<VirtualScrollItemContext<T>>>();\n\n /** Unique ID for this scroll container (used for auto-scroll registration) */\n scrollContainerId = input<string>();\n\n /** Whether auto-scroll is enabled when dragging near edges */\n autoScrollEnabled = input<boolean>(true);\n\n /** Auto-scroll configuration */\n autoScrollConfig = input<Partial<AutoScrollConfig>>({});\n\n /** Array of items to render */\n items = input.required<T[]>();\n\n /** Height of each item in pixels (used as estimate in dynamic mode) */\n itemHeight = input.required<number>();\n\n /**\n * Enable dynamic item height mode.\n * When true, items are auto-measured via ResizeObserver and `itemHeight`\n * serves as the initial estimate for unmeasured items.\n */\n dynamicItemHeight = input<boolean>(false);\n\n /**\n * Height of the container in pixels.\n * If not provided, the container will automatically measure its height from CSS.\n * This allows you to set the height via CSS (e.g., flex, height: 100%, etc.)\n * and the component will adapt automatically, including on resize.\n */\n containerHeight = input<number>();\n\n /**\n * Effective height used for calculations.\n * Uses explicit containerHeight if provided, otherwise uses measured height.\n */\n readonly effectiveHeight = computed(() => this.containerHeight() ?? this.#measuredHeight());\n\n /** Number of items to render above/below the visible area */\n overscan = input<number>(3);\n\n /** IDs of items that should always be rendered (e.g., dragged items) */\n stickyItemIds = input<string[]>([]);\n\n /** Function to get a unique ID from an item */\n itemIdFn = input.required<(item: T) => string>();\n\n /**\n * Track-by function for the @for loop.\n * Optional - if not provided, will be derived from itemIdFn.\n */\n trackByFn = input<(index: number, item: T) => string | number>();\n\n /**\n * ID of the droppable this virtual scroll belongs to.\n * Required for placeholder positioning.\n */\n droppableId = input<string>();\n\n /**\n * Whether to automatically add the dragged item to the sticky list.\n * This ensures the dragged item remains visible during virtual scrolling.\n * @default true\n */\n autoStickyDraggedItem = input<boolean>(true);\n\n // ========== Strategy ==========\n\n /** The virtual scroll strategy, created based on dynamicItemHeight input */\n readonly #strategy = computed<VirtualScrollStrategy>(() => {\n const height = this.itemHeight();\n return this.dynamicItemHeight()\n ? new DynamicHeightStrategy(height)\n : new FixedHeightStrategy(height);\n });\n\n /**\n * Effective track-by function - uses provided trackByFn or derives from itemIdFn.\n */\n protected readonly effectiveTrackByFn = computed(() => {\n const userFn = this.trackByFn();\n if (userFn) return userFn;\n\n const idFn = this.itemIdFn();\n return (_index: number, item: T) => idFn(item);\n });\n\n /**\n * Track function for rendered entries (items + placeholder).\n */\n protected trackEntry(\n _index: number,\n entry: { type: 'item' | 'placeholder'; data: T | null; index: number },\n ): string | number {\n if (entry.type === 'placeholder') {\n return '__placeholder__';\n }\n const trackFn = this.effectiveTrackByFn();\n return trackFn(entry.index, entry.data as T);\n }\n\n /**\n * Effective sticky item IDs - combines user-provided IDs with auto-sticky dragged item.\n */\n protected readonly effectiveStickyIds = computed(() => {\n const userIds = this.stickyItemIds();\n\n if (!this.autoStickyDraggedItem()) {\n return userIds;\n }\n\n const draggedId = this.draggedItemId();\n if (!draggedId) {\n return userIds;\n }\n\n // Avoid creating new array if dragged ID is already in the list\n if (userIds.includes(draggedId)) {\n return userIds;\n }\n\n return [...userIds, draggedId];\n });\n\n /** Current scroll position */\n readonly #scrollTop = signal(0);\n\n /** Total height of all items (for scrollbar) */\n protected readonly totalHeight = computed(() => {\n const count = this.items().length;\n const strategy = this.#strategy();\n strategy.version();\n return strategy.getTotalHeight(count);\n });\n\n /** First visible item index */\n readonly #firstVisibleIndex = computed(() => {\n const strategy = this.#strategy();\n strategy.version();\n return strategy.getFirstVisibleIndex(this.#scrollTop());\n });\n\n /** Number of items visible in the viewport */\n readonly #visibleCount = computed(() => {\n const height = this.effectiveHeight();\n const strategy = this.#strategy();\n strategy.version();\n return strategy.getVisibleCount(this.#firstVisibleIndex(), height);\n });\n\n /** Range of items to render (with overscan) */\n readonly #renderRange = computed(() => {\n const first = this.#firstVisibleIndex();\n const visible = this.#visibleCount();\n const overscan = this.overscan();\n const total = this.items().length;\n\n const start = Math.max(0, first - overscan);\n const end = Math.min(total - 1, first + visible + overscan);\n\n return { start, end };\n });\n\n /** Transform offset for content wrapper (position of first rendered item) */\n protected readonly contentTransform = computed(() => {\n const { start } = this.#renderRange();\n const strategy = this.#strategy();\n strategy.version();\n\n const offset = strategy.getOffsetForIndex(start);\n return `translateY(${offset}px)`;\n });\n\n /** The ID of the currently dragged item (if any) */\n protected readonly draggedItemId = computed(() => {\n return this.#dragState.draggedItem()?.draggableId ?? null;\n });\n\n /** Map of item IDs to their indices - rebuilt only when items() changes (O(n) once, then O(1) lookups) */\n readonly #itemIndexMap = computed(() => {\n const items = this.items();\n const idFn = this.itemIdFn();\n const map = new Map<string, number>();\n for (let i = 0; i < items.length; i++) {\n map.set(idFn(items[i]), i);\n }\n return map;\n });\n\n /** The index of the currently dragged item in the items array (-1 if not found or not dragging) */\n readonly #draggedItemIndex = computed(() => {\n const draggedId = this.draggedItemId();\n if (!draggedId) return -1;\n return this.#itemIndexMap().get(draggedId) ?? -1;\n });\n\n /** Memoized Set of sticky IDs - rebuilt only when effectiveStickyIds() changes */\n readonly #stickyIdsSet = computed(() => new Set(this.effectiveStickyIds()));\n\n /** Whether the placeholder should be shown in this container */\n protected readonly shouldShowPlaceholder = computed(() => {\n if (!this.#dragState.isDragging()) return false;\n return this.#dragState.activeDroppableId() === this.droppableId();\n });\n\n /** The placeholder index when placeholder should be shown */\n protected readonly placeholderIndex = computed(() => {\n if (!this.shouldShowPlaceholder()) return -1;\n return this.#dragState.placeholderIndex() ?? -1;\n });\n\n /** Height for the placeholder — use dragged item's actual height in dynamic mode */\n protected readonly placeholderHeight = computed(() => {\n if (this.dynamicItemHeight()) {\n const draggedItemHeight = this.#dragState.draggedItem()?.height;\n if (draggedItemHeight && draggedItemHeight > 0) return draggedItemHeight;\n }\n return this.itemHeight();\n });\n\n /** Items to render, including sticky items and placeholder */\n protected readonly renderedItems = computed(() => {\n const items = this.items();\n const { start, end } = this.#renderRange();\n const stickyIds = this.#stickyIdsSet();\n const idFn = this.itemIdFn();\n const itemIndexMap = this.#itemIndexMap();\n const draggedId = this.draggedItemId();\n const placeholderIdx = this.placeholderIndex();\n\n const result: {\n type: 'item' | 'placeholder';\n data: T | null;\n index: number;\n isSticky: boolean;\n // The template doesn't read it, but subclasses can: renderedItems is protected\n isDragging: boolean;\n }[] = [];\n const renderedIds = new Set<string>();\n let hasPlaceholder = false;\n\n // Add all items in the visible range, inserting placeholder at correct position\n for (let i = start; i <= end && i < items.length; i++) {\n // Insert placeholder before item at placeholderIndex\n if (placeholderIdx === i && !hasPlaceholder) {\n result.push({\n type: 'placeholder',\n data: null,\n index: placeholderIdx,\n isSticky: false,\n isDragging: false,\n });\n hasPlaceholder = true;\n }\n\n const item = items[i];\n const id = idFn(item);\n result.push({\n type: 'item',\n data: item,\n index: i,\n isSticky: stickyIds.has(id),\n isDragging: id === draggedId,\n });\n renderedIds.add(id);\n }\n\n // If placeholder is at the end (after all items), add it\n if (placeholderIdx >= items.length && placeholderIdx >= 0 && !hasPlaceholder) {\n result.push({\n type: 'placeholder',\n data: null,\n index: placeholderIdx,\n isSticky: false,\n isDragging: false,\n });\n hasPlaceholder = true;\n }\n\n // Add any sticky items that aren't already rendered\n const missingStickyIndices: { id: string; index: number }[] = [];\n for (const id of stickyIds) {\n if (renderedIds.has(id)) continue;\n const index = itemIndexMap.get(id);\n if (index === undefined) continue;\n missingStickyIndices.push({ id, index });\n }\n if (missingStickyIndices.length > 1) {\n missingStickyIndices.sort((a, b) => a.index - b.index);\n }\n\n for (const { id, index } of missingStickyIndices) {\n const item = items[index];\n if (item === undefined) continue;\n result.push({\n type: 'item',\n data: item,\n index,\n isSticky: true,\n isDragging: id === draggedId,\n });\n }\n\n return result;\n });\n\n /** Generated ID for auto-scroll registration */\n #generatedScrollId = `vdnd-scroll-${Math.random().toString(36).slice(2, 9)}`;\n\n /** Track previous dragged ID to detect drag end */\n #previousDraggedId: string | null = null;\n\n /** Track previous total height to detect if we were at bottom before drag ended */\n #previousTotalHeight = 0;\n\n constructor() {\n createAutoScrollRegistration({\n autoScrollService: this.#autoScrollService,\n getElement: () => this.#elementRef.nativeElement,\n getId: () => this.scrollContainerId() ?? this.#generatedScrollId,\n enabled: () => this.autoScrollEnabled(),\n config: () => this.autoScrollConfig(),\n });\n\n // Keep strategy item keys in sync\n effect(() => {\n const items = this.items();\n const idFn = this.itemIdFn();\n const keys = items.map((item) => idFn(item));\n this.#strategy().setItemKeys(keys);\n });\n\n // Register strategy with drag index calculator for accurate drag calculations\n effect((onCleanup) => {\n const droppableId = this.droppableId();\n const strategy = this.#strategy();\n if (droppableId) {\n this.#dragIndexCalculator.registerStrategy(droppableId, strategy);\n onCleanup(() => this.#dragIndexCalculator.unregisterStrategy(droppableId));\n }\n });\n\n // Set excluded index persistently during same-list drag.\n effect(() => {\n const strategy = this.#strategy();\n const draggedIndex = this.#draggedItemIndex();\n strategy.setExcludedIndex(draggedIndex >= 0 ? draggedIndex : null);\n });\n\n // Snapshot item positions before the template re-renders the placeholder move.\n // Component effects run before the component's own template is refreshed.\n if (this.#shiftAnimator) {\n const animator = this.#shiftAnimator;\n effect(() => {\n const isDragging = this.#dragState.isDragging();\n const placeholderIndex = this.placeholderIndex();\n untracked(() => animator.beforeUpdate(isDragging, placeholderIndex));\n });\n }\n\n // Keyboard drag autoscroll: keep the placeholder visible. Arrow keys call\n // #revealPlaceholder synchronously (through KeyboardDragService) so a drop right after a\n // move never lands outside the rendered range; this effect re-runs it when item\n // measurements or the viewport height change during the drag.\n effect((onCleanup) => {\n const droppableId = this.droppableId();\n if (!droppableId) return;\n const reveal = (): void => untracked(() => this.#revealPlaceholder());\n this.#keyboardDrag.registerRevealer(droppableId, reveal);\n onCleanup(() => this.#keyboardDrag.unregisterRevealer(droppableId, reveal));\n });\n effect(() => this.#revealPlaceholder());\n\n // Preserve scroll position when drag ends at bottom of list.\n // Safety net: totalHeight no longer shrinks during drag (getTotalHeight\n // ignores exclusion), but this logic remains as harmless protection\n // in case future changes reintroduce height variance.\n effect(() => {\n const currentDraggedId = this.draggedItemId();\n const currentTotalHeight = this.totalHeight();\n const element = this.#elementRef.nativeElement;\n\n // Detect drag end (was dragging, now not)\n if (this.#previousDraggedId !== null && currentDraggedId === null) {\n const currentScrollTop = element.scrollTop;\n const strategy = this.#strategy();\n strategy.version();\n const height = this.effectiveHeight();\n const totalItems = this.items().length;\n\n // Calculate if we were at/near bottom (within 10px tolerance)\n // using the height FROM THE PREVIOUS CYCLE (when dragging was active)\n const dragReducedMaxScroll = Math.max(0, this.#previousTotalHeight - height);\n const wasAtBottom = currentScrollTop >= dragReducedMaxScroll - 10;\n\n if (wasAtBottom && dragReducedMaxScroll > 0) {\n // Clear exclusion before calculating new height\n strategy.setExcludedIndex(null);\n\n // Adjust scroll to new bottom position after totalHeight increases\n afterNextRender(\n () => {\n const newTotalHeight = strategy.getTotalHeight(totalItems);\n const newMaxScroll = Math.max(0, newTotalHeight - height);\n element.scrollTop = newMaxScroll;\n this.#scrollTop.set(newMaxScroll);\n },\n { injector: this.#injector },\n );\n }\n }\n\n this.#previousDraggedId = currentDraggedId;\n this.#previousTotalHeight = currentTotalHeight;\n });\n\n // Clamp scrollTop during drag if totalHeight ever shrinks.\n // With the current fix, getTotalHeight no longer excludes the dragged item,\n // so this is effectively a no-op. Kept as a safety net.\n effect(() => {\n const isDragging = this.#dragState.isDragging();\n const totalHeight = this.totalHeight();\n const element = this.#elementRef.nativeElement;\n\n if (isDragging) {\n const containerHeight = this.effectiveHeight();\n const maxScroll = Math.max(0, totalHeight - containerHeight);\n const currentScrollTop = element.scrollTop;\n\n // Clamp scrollTop to valid range\n if (currentScrollTop > maxScroll) {\n element.scrollTop = maxScroll;\n this.#scrollTop.set(maxScroll);\n }\n }\n });\n }\n\n ngOnInit(): void {\n // Measure rows in dynamic height mode. dynamicItemHeight can change at runtime, and the\n // strategy is replaced when it (or itemHeight) does, so this creates, replaces or removes the\n // observer. #observeRenderedItems observes every rendered row with each new observer, so a\n // new strategy gets their heights.\n effect(\n (onCleanup) => {\n // No ResizeObserver during server rendering\n if (!this.dynamicItemHeight() || !this.#isBrowser) return;\n this.#strategy();\n const observer = untracked(() => this.#createItemResizeObserver());\n this.#itemResizeObserver.set(observer);\n onCleanup(() => {\n observer.disconnect();\n this.#observedElementByKey.clear();\n this.#itemResizeObserver.set(null);\n });\n },\n { injector: this.#injector },\n );\n }\n\n ngAfterViewInit(): void {\n const element = this.#elementRef.nativeElement;\n\n this.#resizeCleanup = bindResizeObserverHeightSignal({\n element,\n ngZone: this.#ngZone,\n height: this.#measuredHeight,\n minDeltaPx: 1,\n });\n\n // Scroll listener outside Angular zone with RAF throttling.\n // This avoids template event binding which would mark the component dirty 60x/sec.\n this.#scrollCleanup = bindRafThrottledScrollTopSignal({\n element,\n ngZone: this.#ngZone,\n scrollTop: this.#scrollTop,\n thresholdPx: 5,\n });\n\n // Observe rendered items for dynamic height measurement\n this.#observeRenderedItems();\n }\n\n /**\n * Scroll so the placeholder is fully visible during a keyboard drag into this list.\n * Reads only signals and strategy offsets, so it works before the placeholder renders.\n */\n #revealPlaceholder(): void {\n // Only apply when this droppable is active during keyboard drag\n if (!this.#dragState.isKeyboardDrag()) return;\n const activeDroppable = this.#dragState.activeDroppableId();\n if (activeDroppable !== this.droppableId()) return;\n\n // The placeholder renders before the item at placeholderIndex. Below the source in the\n // same list that is keyboardTargetIndex + 1: the dragged item's slot is excluded.\n if (this.#dragState.keyboardTargetIndex() === null) return;\n const placeholderIndex = this.placeholderIndex();\n if (placeholderIndex < 0) return;\n\n const strategy = this.#strategy();\n strategy.version();\n const height = this.effectiveHeight();\n if (height <= 0) return;\n\n const element = this.#elementRef.nativeElement;\n const currentScrollTop = element.scrollTop;\n\n // Calculate placeholder position using strategy\n const targetTop = strategy.getOffsetForIndex(placeholderIndex);\n const targetBottom = targetTop + this.placeholderHeight();\n\n // Calculate visible range\n const viewportTop = currentScrollTop;\n const viewportBottom = currentScrollTop + height;\n\n // Check if target is fully visible\n if (targetTop < viewportTop) {\n // Target is above viewport - scroll up\n element.scrollTop = targetTop;\n this.#scrollTop.set(targetTop);\n } else if (targetBottom > viewportBottom) {\n // Target is below viewport - scroll down\n const newScrollTop = targetBottom - height;\n element.scrollTop = newScrollTop;\n this.#scrollTop.set(newScrollTop);\n }\n }\n\n ngOnDestroy(): void {\n this.#scrollCleanup?.();\n this.#resizeCleanup?.();\n const itemResizeObserver = this.#itemResizeObserver();\n for (const element of this.#observedElementByKey.values()) {\n itemResizeObserver?.unobserve(element);\n }\n this.#observedElementByKey.clear();\n itemResizeObserver?.disconnect();\n this.#shiftAnimator?.cancelAll();\n }\n\n #createShiftAnimator(): ShiftAnimator | null {\n const config = inject(VDND_ANIMATION_CONFIG, { optional: true });\n if (!config) return null;\n return new ShiftAnimator({\n config,\n injector: this.#injector,\n getScrollElement: () => this.#elementRef.nativeElement,\n getEntries: () => this.#shiftAnimationEntries(),\n });\n }\n\n /**\n * Rendered item roots and the placeholder. `@for` never reuses a view for a different\n * track key, so each element is its own stable identity.\n */\n *#shiftAnimationEntries(): Iterable<ShiftAnimationEntry> {\n const wrapper = this.#elementRef.nativeElement.querySelector(\n '.vdnd-virtual-scroll-content-wrapper',\n );\n if (!wrapper) return;\n for (const child of Array.from(wrapper.children)) {\n if (child instanceof HTMLElement) {\n yield [child, child];\n }\n }\n }\n\n /**\n * Create the ResizeObserver that measures individual item heights.\n */\n #createItemResizeObserver(): ResizeObserver {\n return this.#ngZone.runOutsideAngular(\n () =>\n new ResizeObserver((entries) => {\n const strategy = this.#strategy();\n for (const entry of entries) {\n const element = entry.target as HTMLElement;\n const key = this.#observedElements.get(element);\n if (key === undefined) continue;\n\n const height = entry.borderBoxSize?.[0]?.blockSize ?? element.offsetHeight;\n if (height > 0) {\n strategy.setMeasuredHeight(key, height);\n }\n }\n }),\n );\n }\n\n /**\n * Observe currently rendered items' DOM elements for height changes.\n * Called after view init; re-observes after each render in dynamic mode, and every rendered\n * item when a new observer is created.\n */\n #observeRenderedItems(): void {\n // Re-observe whenever rendered items change, once they are in the DOM (a plain effect runs\n // before the template renders them, so newly rendered rows would be missed)\n afterRenderEffect(\n () => {\n const observer = this.#itemResizeObserver();\n if (!observer) return;\n const rendered = this.renderedItems();\n const idFn = this.itemIdFn();\n\n // Find the content wrapper and observe item elements\n const wrapper = this.#elementRef.nativeElement.querySelector(\n '.vdnd-virtual-scroll-content-wrapper',\n );\n if (!wrapper) return;\n\n const nextObservedByKey = new Map<unknown, HTMLElement>();\n\n for (const entry of rendered) {\n if (entry.type !== 'item' || !entry.data) continue;\n const key = idFn(entry.data);\n\n // Find the DOM element for this item by its data-draggable-id.\n const el = queryByAttribute<HTMLElement>(wrapper, 'data-draggable-id', key);\n if (el) {\n nextObservedByKey.set(key, el);\n }\n }\n\n for (const [key, oldElement] of this.#observedElementByKey) {\n const nextElement = nextObservedByKey.get(key);\n if (nextElement !== oldElement) {\n observer.unobserve(oldElement);\n }\n }\n\n for (const [key, nextElement] of nextObservedByKey) {\n const currentElement = this.#observedElementByKey.get(key);\n if (currentElement !== nextElement) {\n this.#observedElements.set(nextElement, key);\n observer.observe(nextElement);\n }\n }\n\n this.#observedElementByKey.clear();\n for (const [key, element] of nextObservedByKey) {\n this.#observedElementByKey.set(key, element);\n }\n },\n { injector: this.#injector },\n );\n }\n\n /**\n * Scroll to a specific position.\n */\n scrollTo(position: number): void {\n const element = this.#elementRef.nativeElement;\n element.scrollTop = position;\n // Store where the browser actually scrolled. It clamps to the scrollable range, and if that\n // leaves the element where it was, no scroll event arrives to correct an out-of-range value.\n this.#scrollTop.set(element.scrollTop);\n }\n\n /**\n * Scroll to a specific item index.\n */\n scrollToIndex(index: number): void {\n const strategy = this.#strategy();\n const position = strategy.getOffsetForIndex(index);\n this.scrollTo(position);\n }\n\n /**\n * Get the current scroll position.\n */\n getScrollTop(): number {\n return this.#scrollTop();\n }\n\n /**\n * Get the total scrollable height.\n */\n getScrollHeight(): number {\n return this.totalHeight();\n }\n\n /**\n * Scroll by a delta amount.\n */\n scrollBy(delta: number): void {\n const newPosition = Math.max(\n 0,\n Math.min(this.getScrollTop() + delta, this.getScrollHeight() - this.effectiveHeight()),\n );\n this.scrollTo(newPosition);\n }\n}\n","import {\n DEFAULT_DROP_DURATION,\n DEFAULT_DROP_EASING,\n type VdndAnimationConfig,\n} from '../tokens/animation-config.token';\nimport { queryByAttribute } from './attribute-selectors';\n\n/** Where the ghost should land, and the element that stands there. */\nexport interface DropAnimationTarget {\n /** The dropped item's rendered element (hidden until the ghost lands) */\n element: HTMLElement;\n /** Its viewport rect */\n rect: DOMRect;\n}\n\n/**\n * Plays the drop (\"settle\") animation: the drag preview glides from where it was released\n * into the dropped item's final position, while that item stays invisible underneath.\n *\n * Purely visual. The drag state and the drop events are already final when it starts, so it\n * never delays or changes a drop. Without a target (the item is not rendered, or scrolled out\n * of view) the ghost fades out where it was released.\n * @internal\n */\nexport class DropAnimator {\n readonly #config: VdndAnimationConfig;\n\n #ghostAnimation: Animation | null = null;\n #hideAnimation: Animation | null = null;\n\n constructor(config: VdndAnimationConfig) {\n this.#config = config;\n }\n\n /** Whether a drop animation would play right now (duration, WAAPI, reduced motion). */\n isEnabled(): boolean {\n if (this.#duration() <= 0) return false;\n if (typeof Element === 'undefined' || typeof Element.prototype.animate !== 'function') {\n return false;\n }\n if (typeof matchMedia !== 'function') return true;\n return !matchMedia('(prefers-reduced-motion: reduce)').matches;\n }\n\n /**\n * Animate `ghost` onto `target` (or fade it out without one), then call `onDone`.\n * `onDone` is not called when the animation is cancelled.\n */\n play(ghost: HTMLElement, target: DropAnimationTarget | null, onDone: () => void): void {\n this.cancel();\n\n const timing: KeyframeAnimationOptions = {\n duration: this.#duration(),\n easing: this.#config.dropEasing ?? DEFAULT_DROP_EASING,\n fill: 'forwards',\n };\n\n let ghostAnimation: Animation;\n if (target) {\n const from = ghost.getBoundingClientRect();\n const dx = target.rect.left - from.left;\n const dy = target.rect.top - from.top;\n // Travel on top of the preview's own position transform (width/height must not be\n // composited, so the base transform is repeated instead of using composite: 'add').\n const base = ghost.style.transform;\n ghostAnimation = ghost.animate(\n [\n {\n transform: `${base} translate(0px, 0px)`,\n width: `${from.width}px`,\n height: `${from.height}px`,\n },\n {\n transform: `${base} translate(${dx}px, ${dy}px)`,\n width: `${target.rect.width}px`,\n height: `${target.rect.height}px`,\n },\n ],\n timing,\n );\n // Keep the real item invisible until the ghost lands on it, so it is never seen twice.\n this.#hideAnimation = target.element.animate([{ opacity: 0 }, { opacity: 0 }], {\n duration: timing.duration,\n });\n } else {\n ghostAnimation = ghost.animate([{ opacity: 1 }, { opacity: 0 }], timing);\n }\n\n this.#ghostAnimation = ghostAnimation;\n ghostAnimation.onfinish = () => {\n if (this.#ghostAnimation !== ghostAnimation) return;\n this.cancel();\n onDone();\n };\n }\n\n /** Stop the running animation immediately and reveal the real item. */\n cancel(): void {\n const ghostAnimation = this.#ghostAnimation;\n const hideAnimation = this.#hideAnimation;\n this.#ghostAnimation = null;\n this.#hideAnimation = null;\n ghostAnimation?.cancel();\n hideAnimation?.cancel();\n }\n\n #duration(): number {\n return this.#config.dropDuration ?? DEFAULT_DROP_DURATION;\n }\n}\n\n/**\n * Find the rendered element of a dropped item: first in the droppable it was dropped on, then\n * in the one it came from (a drop the consumer rejected or has not committed yet leaves it\n * there). Returns null when it is not rendered, or rendered but scrolled out of its list's view.\n */\nexport function findDropTarget(\n draggableId: string,\n droppableIds: readonly (string | null | undefined)[],\n): DropAnimationTarget | null {\n if (typeof document === 'undefined') return null;\n\n for (const droppableId of droppableIds) {\n if (!droppableId) continue;\n const droppable = queryByAttribute<HTMLElement>(document, 'data-droppable-id', droppableId);\n const element = droppable\n ? queryByAttribute<HTMLElement>(droppable, 'data-draggable-id', draggableId)\n : null;\n if (!droppable || !element) continue;\n\n const rect = element.getBoundingClientRect();\n // Hidden, or virtualized/scrolled out of the list's visible box: nowhere to land.\n if (rect.width === 0 && rect.height === 0) return null;\n const bounds = droppable.getBoundingClientRect();\n const visible =\n rect.bottom > bounds.top &&\n rect.top < bounds.bottom &&\n rect.right > bounds.left &&\n rect.left < bounds.right;\n return visible ? { element, rect } : null;\n }\n return null;\n}\n","import {\n afterNextRender,\n ChangeDetectionStrategy,\n Component,\n computed,\n effect,\n ElementRef,\n inject,\n Injector,\n input,\n OnDestroy,\n signal,\n TemplateRef,\n untracked,\n viewChild,\n} from '@angular/core';\nimport { NgTemplateOutlet } from '@angular/common';\nimport { DragStateService } from '../services/drag-state.service';\nimport { OverlayContainerService } from '../services/overlay-container.service';\nimport { CursorPosition, DraggedItem, DragState } from '../models/drag-drop.models';\nimport { VDND_ANIMATION_CONFIG } from '../tokens/animation-config.token';\nimport { DropAnimator, findDropTarget } from '../utils/drop-animator';\n\n/**\n * Context provided to the drag preview template.\n */\nexport interface DragPreviewContext<T = unknown> {\n /** The data associated with the dragged item */\n $implicit: T;\n /** The draggable ID */\n draggableId: string;\n /** The source droppable ID */\n droppableId: string;\n}\n\n/** A preview that outlives its drag while it glides into the drop position. */\ninterface SettlingPreview {\n item: DraggedItem;\n position: CursorPosition;\n}\n\n/**\n * Renders a preview of the dragged item that follows the cursor.\n *\n * The component automatically teleports itself into a body-level overlay container,\n * so it works correctly even inside ancestors with CSS `transform` (e.g. Ionic pages).\n * It can be placed anywhere in the component tree.\n *\n * When `VDND_ANIMATION_CONFIG` is provided, the preview stays up briefly after a drop or\n * cancel and glides into the item's final position.\n *\n * @example\n * ```html\n * <vdnd-drag-preview>\n * <ng-template let-data let-id=\"draggableId\">\n * <div class=\"drag-preview\">{{ data.name }}</div>\n * </ng-template>\n * </vdnd-drag-preview>\n * ```\n */\n@Component({\n selector: 'vdnd-drag-preview',\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [NgTemplateOutlet],\n template: `\n @if (isVisible()) {\n <div\n #preview\n class=\"vdnd-drag-preview\"\n [class.vdnd-drag-preview-dropping]=\"isSettling()\"\n [attr.data-testid]=\"isSettling() ? 'vdnd-drag-preview-dropping' : 'vdnd-drag-preview'\"\n [style.transform]=\"transform()\"\n [style.width.px]=\"dimensions().width\"\n [style.height.px]=\"dimensions().height\"\n >\n @if (previewTemplate()) {\n <ng-container *ngTemplateOutlet=\"previewTemplate()!; context: templateContext()\">\n </ng-container>\n } @else if (clonedElement()) {\n <div class=\"vdnd-drag-preview-clone\" #cloneContainer></div>\n } @else {\n <div class=\"vdnd-drag-preview-default\">\n {{ displayedItem()?.draggableId }}\n </div>\n }\n </div>\n }\n `,\n styles: `\n .vdnd-drag-preview {\n box-sizing: border-box;\n position: fixed;\n left: 0;\n top: 0;\n will-change: transform;\n pointer-events: none;\n z-index: 1000;\n }\n\n .vdnd-drag-preview-clone {\n width: 100%;\n height: 100%;\n overflow: hidden;\n }\n `,\n})\nexport class DragPreviewComponent<T = unknown> implements OnDestroy {\n protected readonly dragState = inject(DragStateService);\n readonly #overlayContainer = inject(OverlayContainerService);\n readonly #elementRef = inject(ElementRef<HTMLElement>);\n readonly #injector = inject(Injector);\n readonly #dropAnimator = this.#createDropAnimator();\n\n /** Optional custom template for the preview */\n previewTemplate = input<TemplateRef<DragPreviewContext<T>>>();\n\n /** Offset from cursor to preview (to avoid cursor being on top of preview) */\n cursorOffset = input<{ x: number; y: number }>({ x: 8, y: 8 });\n\n /** Reference to the clone container element (cannot use ES private with viewChild) */\n private readonly cloneContainer = viewChild<ElementRef<HTMLElement>>('cloneContainer');\n\n /** The rendered preview box (cannot use ES private with viewChild) */\n private readonly previewElement = viewChild<ElementRef<HTMLElement>>('preview');\n\n /** Set while the preview animates into the drop position after the drag ended */\n readonly #settling = signal<SettlingPreview | null>(null);\n\n /** Whether the drag was still active on the last state change (detects drag end) */\n #wasDragging = false;\n\n /** Whether the preview is playing the drop animation */\n protected readonly isSettling = computed(() => this.#settling() !== null);\n\n /** The item shown: the live dragged item, or the dropped one while it settles */\n protected readonly displayedItem = computed(\n () => this.dragState.draggedItem() ?? this.#settling()?.item ?? null,\n );\n\n /** Whether this preview's template registration is currently counted (kept balanced). */\n #templateRegistered = false;\n\n /** The cloned element from drag state (used when no custom template is provided) */\n protected readonly clonedElement = computed(() => {\n if (this.previewTemplate()) {\n return null; // Custom template takes precedence\n }\n return this.displayedItem()?.clonedElement ?? null;\n });\n\n constructor() {\n // Teleport host element into the body-level overlay container after first render.\n // This escapes any ancestor CSS transforms that would break position: fixed.\n afterNextRender(() => {\n const container = this.#overlayContainer.getContainerElement();\n if (container) {\n container.appendChild(this.#elementRef.nativeElement);\n }\n });\n\n // Publish whether this preview renders via a custom template so the drag\n // directives can skip the drag-start element clone when it won't be shown.\n effect(() => {\n const hasTemplate = !!this.previewTemplate();\n if (hasTemplate && !this.#templateRegistered) {\n this.#overlayContainer.setTemplatePreviewActive(true);\n this.#templateRegistered = true;\n } else if (!hasTemplate && this.#templateRegistered) {\n this.#overlayContainer.setTemplatePreviewActive(false);\n this.#templateRegistered = false;\n }\n });\n\n // Effect to insert the cloned element into the container\n effect(() => {\n const container = this.cloneContainer()?.nativeElement;\n const clone = this.clonedElement();\n\n if (!container) {\n return;\n }\n\n // Clear previous content and append the prepared clone element.\n // Avoid cloning again: ElementCloneService already creates a styled/sanitized clone.\n container.innerHTML = '';\n if (clone) {\n container.appendChild(clone);\n }\n });\n\n // Drop animation: when a drag ends, keep the preview up and glide it into place.\n // A new drag cuts any settle short.\n effect(() => {\n const isDragging = this.dragState.isDragging();\n untracked(() => {\n const wasDragging = this.#wasDragging;\n this.#wasDragging = isDragging;\n if (isDragging) {\n this.#stopSettling();\n } else if (wasDragging) {\n this.#startSettling();\n }\n });\n });\n }\n\n ngOnDestroy(): void {\n this.#dropAnimator?.cancel();\n if (this.#templateRegistered) {\n this.#overlayContainer.setTemplatePreviewActive(false);\n this.#templateRegistered = false;\n }\n this.#elementRef.nativeElement.remove();\n }\n\n /** Whether the preview is visible */\n protected readonly isVisible = computed(() => {\n return (\n (this.dragState.isDragging() && this.dragState.cursorPosition() !== null) || this.isSettling()\n );\n });\n\n /** Position of the preview */\n protected readonly position = computed(() => {\n const settling = this.#settling();\n if (settling && !this.dragState.isDragging()) {\n return settling.position;\n }\n return this.#positionFor({\n cursorPosition: this.dragState.cursorPosition(),\n grabOffset: this.dragState.grabOffset(),\n initialPosition: this.dragState.initialPosition(),\n lockAxis: this.dragState.lockAxis(),\n });\n });\n\n #positionFor(\n state: Pick<DragState, 'cursorPosition' | 'grabOffset' | 'initialPosition' | 'lockAxis'>,\n ): CursorPosition {\n const cursor = state.cursorPosition;\n const initialPosition = state.initialPosition;\n const lockAxis = state.lockAxis;\n\n if (!cursor) {\n return { x: 0, y: 0 };\n }\n\n // Use grab offset if available (preserves grab position), otherwise fall back to cursorOffset input\n const offset = state.grabOffset ?? this.cursorOffset();\n\n let x = cursor.x - offset.x;\n let y = cursor.y - offset.y;\n\n // Apply axis locking if configured\n if (lockAxis && initialPosition) {\n if (lockAxis === 'x') {\n // Lock X axis: x stays at initial position\n x = initialPosition.x - offset.x;\n } else if (lockAxis === 'y') {\n // Lock Y axis: y stays at initial position\n y = initialPosition.y - offset.y;\n }\n }\n\n return { x, y };\n }\n\n /** Transform-based positioning for better performance (avoid layout from left/top). */\n protected readonly transform = computed(() => {\n const { x, y } = this.position();\n return `translate3d(${x}px, ${y}px, 0)`;\n });\n\n /** Dimensions of the preview */\n protected readonly dimensions = computed(() => {\n const item = this.displayedItem();\n\n if (!item) {\n return { width: 100, height: 50 };\n }\n\n return {\n width: item.width,\n height: item.height,\n };\n });\n\n /** Template context */\n protected readonly templateContext = computed((): DragPreviewContext<T> => {\n const item = this.displayedItem();\n\n return {\n $implicit: (item?.data ?? null) as T,\n draggableId: item?.draggableId ?? '',\n droppableId: item?.droppableId ?? '',\n };\n });\n\n #createDropAnimator(): DropAnimator | null {\n const config = inject(VDND_ANIMATION_CONFIG, { optional: true });\n return config ? new DropAnimator(config) : null;\n }\n\n /**\n * Keep the ended drag's preview on screen, then (once the consumer's drop handler has\n * re-rendered the lists) animate it onto the item's final position.\n */\n #startSettling(): void {\n const ended = this.dragState.endedDragState();\n if (!this.#dropAnimator?.isEnabled() || !ended?.draggedItem || !ended.cursorPosition) {\n return;\n }\n\n const settling: SettlingPreview = {\n item: ended.draggedItem,\n position: this.#positionFor(ended),\n };\n this.#settling.set(settling);\n\n // A normal drop lands in the target list; a cancel, a rejected drop or one the consumer\n // has not committed yet leaves the item in its source list.\n const droppableIds = this.dragState.wasCancelled()\n ? [ended.sourceDroppableId]\n : [ended.activeDroppableId, ended.sourceDroppableId];\n\n afterNextRender(\n () => {\n if (this.#settling() !== settling) {\n return;\n }\n const ghost = this.previewElement()?.nativeElement;\n if (!ghost || !this.#dropAnimator) {\n this.#settling.set(null);\n return;\n }\n const target = findDropTarget(settling.item.draggableId, droppableIds);\n this.#dropAnimator.play(ghost, target, () => {\n if (this.#settling() === settling) {\n this.#settling.set(null);\n }\n });\n },\n { injector: this.#injector },\n );\n }\n\n #stopSettling(): void {\n this.#dropAnimator?.cancel();\n this.#settling.set(null);\n }\n}\n","import { ChangeDetectionStrategy, Component, input, TemplateRef } from '@angular/core';\nimport { NgTemplateOutlet } from '@angular/common';\n\n/**\n * Context provided to the custom placeholder template.\n */\nexport interface PlaceholderContext {\n /** The height of the placeholder in pixels */\n $implicit: number;\n /** The height of the placeholder in pixels (explicit property) */\n height: number;\n}\n\n/**\n * A placeholder component that indicates where a dropped item will be inserted.\n *\n * By default, renders as empty/transparent space. Pass a custom template\n * to customize the placeholder appearance.\n *\n * @example\n * ```html\n * <!-- Default: transparent/empty space -->\n * <vdnd-placeholder [height]=\"50\"></vdnd-placeholder>\n *\n * <!-- Custom template with dashed border -->\n * <vdnd-placeholder [height]=\"50\" [template]=\"customPlaceholder\">\n * <ng-template #customPlaceholder let-height>\n * <div class=\"my-placeholder\" [style.height.px]=\"height\">\n * Drop here\n * </div>\n * </ng-template>\n * </vdnd-placeholder>\n * ```\n */\n@Component({\n selector: 'vdnd-placeholder',\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [NgTemplateOutlet],\n host: {\n class: 'vdnd-placeholder',\n '[style.height.px]': 'height()',\n '[attr.data-draggable-id]': '\"placeholder\"',\n },\n template: `\n @if (template()) {\n <ng-container\n *ngTemplateOutlet=\"template()!; context: { $implicit: height(), height: height() }\"\n >\n </ng-container>\n }\n `,\n styles: `\n :host {\n display: block;\n box-sizing: border-box;\n }\n `,\n})\nexport class PlaceholderComponent {\n /** Height of the placeholder in pixels */\n height = input<number>(50);\n\n /** Optional custom template for the placeholder content */\n template = input<TemplateRef<PlaceholderContext>>();\n}\n","import { Directive, InjectionToken, input, Signal } from '@angular/core';\n\n/**\n * Token for injecting the group context from a parent directive.\n * Allows child draggables and droppables to inherit the group name automatically.\n */\nexport const VDND_GROUP_TOKEN = new InjectionToken<VdndGroupContext>('VDND_GROUP_TOKEN');\n\n/**\n * Context provided by the group directive to its children.\n */\nexport interface VdndGroupContext {\n /** The group name signal */\n readonly group: Signal<string>;\n}\n\n/**\n * Provides a group context to child draggable and droppable directives.\n * When applied to a parent element, child directives can inherit the group name\n * automatically without needing to specify it on each element.\n *\n * @example\n * ```html\n * <!-- Without group directive (verbose) -->\n * <div vdndDroppable=\"list-1\" vdndDroppableGroup=\"my-group\">\n * <div vdndDraggable=\"item-1\" vdndDraggableGroup=\"my-group\">Item 1</div>\n * <div vdndDraggable=\"item-2\" vdndDraggableGroup=\"my-group\">Item 2</div>\n * </div>\n *\n * <!-- With group directive (concise) -->\n * <div vdndGroup=\"my-group\">\n * <div vdndDroppable=\"list-1\">\n * <div vdndDraggable=\"item-1\">Item 1</div>\n * <div vdndDraggable=\"item-2\">Item 2</div>\n * </div>\n * </div>\n * ```\n */\n@Directive({\n selector: '[vdndGroup]',\n providers: [\n {\n provide: VDND_GROUP_TOKEN,\n useExisting: DroppableGroupDirective,\n },\n ],\n})\nexport class DroppableGroupDirective implements VdndGroupContext {\n /** The group name that will be inherited by child directives */\n readonly group = input.required<string>({ alias: 'vdndGroup' });\n}\n","import { computed, isDevMode, type Signal } from '@angular/core';\nimport type { VdndGroupContext } from '../directives/droppable-group.directive';\n\n/**\n * Configuration options for creating an effective group signal.\n */\nexport interface GroupResolutionOptions {\n /** The explicit group input signal */\n explicitGroup: Signal<string | undefined>;\n /** The parent group context injected via VDND_GROUP_TOKEN (may be null) */\n parentGroup: VdndGroupContext | null;\n /** The element ID signal for warning messages */\n elementId: Signal<string>;\n /** The type of element ('draggable' or 'droppable') for warning messages */\n elementType: 'draggable' | 'droppable';\n}\n\n/**\n * State tracker for group resolution to avoid repeated warnings.\n */\ninterface GroupResolutionState {\n hasWarnedMissingGroup: boolean;\n}\n\n/**\n * Creates a computed signal that resolves the effective group name for a draggable or droppable.\n *\n * Resolution order:\n * 1. Explicit group input (vdndDraggableGroup or vdndDroppableGroup)\n * 2. Inherited group from parent vdndGroup directive\n * 3. null (with dev-mode warning)\n *\n * @example\n * ```typescript\n * readonly #effectiveGroup = createEffectiveGroupSignal({\n * explicitGroup: this.vdndDraggableGroup,\n * parentGroup: this.#parentGroup,\n * elementId: this.vdndDraggable,\n * elementType: 'draggable',\n * });\n * ```\n */\nexport function createEffectiveGroupSignal(options: GroupResolutionOptions): Signal<string | null> {\n const { explicitGroup, parentGroup, elementId, elementType } = options;\n\n // State object to track whether we've warned (mutable closure state)\n const state: GroupResolutionState = { hasWarnedMissingGroup: false };\n\n return computed((): string | null => {\n const explicit = explicitGroup();\n if (explicit) return explicit;\n\n const inherited = parentGroup?.group();\n if (inherited) return inherited;\n\n if (isDevMode() && !state.hasWarnedMissingGroup) {\n const directive = elementType === 'draggable' ? 'vdndDraggable' : 'vdndDroppable';\n const groupInput = elementType === 'draggable' ? 'vdndDraggableGroup' : 'vdndDroppableGroup';\n const action = elementType === 'draggable' ? 'Drag' : 'Dropping';\n\n console.warn(\n `[ngx-virtual-dnd] [${directive}=\"${elementId()}\"] requires a group. ` +\n `Either set ${groupInput} or wrap in a vdndGroup directive. ` +\n `${action} will be disabled for this element.`,\n );\n state.hasWarnedMissingGroup = true;\n }\n\n return null;\n });\n}\n","/**\n * Normalize a placeholder index into the final same-list insertion index.\n *\n * Same-list drags render a placeholder in a list with the source item hidden, so placeholder\n * indexes after the source include a +1 hidden-source adjustment. Drop consumers receive the\n * post-removal insertion index, which subtracts that adjustment.\n */\nexport function normalizeDropDestinationIndex(args: {\n sourceIndex: number;\n placeholderIndex: number;\n sourceDroppableId: string | null;\n activeDroppableId: string | null;\n}): number;\nexport function normalizeDropDestinationIndex(args: {\n sourceIndex: number;\n placeholderIndex: number | null;\n sourceDroppableId: string | null;\n activeDroppableId: string | null;\n}): number | null;\nexport function normalizeDropDestinationIndex({\n sourceIndex,\n placeholderIndex,\n sourceDroppableId,\n activeDroppableId,\n}: {\n sourceIndex: number;\n placeholderIndex: number | null;\n sourceDroppableId: string | null;\n activeDroppableId: string | null;\n}): number | null {\n if (placeholderIndex === null) {\n return null;\n }\n\n if (\n sourceDroppableId !== null &&\n sourceDroppableId === activeDroppableId &&\n sourceIndex < placeholderIndex\n ) {\n return placeholderIndex - 1;\n }\n\n return placeholderIndex;\n}\n","import {\n afterNextRender,\n computed,\n Directive,\n effect,\n ElementRef,\n inject,\n input,\n OnDestroy,\n output,\n untracked,\n} from '@angular/core';\nimport { DragStateService } from '../services/drag-state.service';\nimport { AutoScrollConfig, AutoScrollService } from '../services/auto-scroll.service';\nimport { PositionCalculatorService } from '../services/position-calculator.service';\nimport {\n DraggedItem,\n DragState,\n DropEvent,\n END_OF_LIST,\n PlaceholderMoveEvent,\n} from '../models/drag-drop.models';\nimport { VDND_GROUP_TOKEN } from './droppable-group.directive';\nimport { createEffectiveGroupSignal } from '../utils/group-resolution';\nimport { createAutoScrollRegistration } from '../utils/auto-scroll-registration';\nimport { queryByAttribute } from '../utils/attribute-selectors';\nimport { normalizeDropDestinationIndex } from '../utils/drop-index-normalization';\n\n/**\n * Marks an element as a valid drop target within the virtual scroll drag-and-drop system.\n *\n * @example\n * ```html\n * <!-- With explicit group -->\n * <div\n * vdndDroppable=\"list-1\"\n * vdndDroppableGroup=\"my-group\"\n * (drop)=\"onDrop($event)\">\n * <!-- Draggable items here -->\n * </div>\n *\n * <!-- With inherited group from parent vdndGroup directive -->\n * <div vdndGroup=\"my-group\">\n * <div vdndDroppable=\"list-1\" (drop)=\"onDrop($event)\">\n * <!-- Draggable items here -->\n * </div>\n * </div>\n * ```\n */\n@Directive({\n selector: '[vdndDroppable]',\n host: {\n '[attr.data-droppable-id]': 'vdndDroppable()',\n '[attr.data-droppable-group]': 'effectiveGroup()',\n '[attr.data-droppable-disabled]': 'disabled() || null',\n '[attr.data-constrain-to-container]': 'constrainToContainer() || null',\n '[attr.aria-dropeffect]': '\"move\"',\n '[class.vdnd-droppable]': 'true',\n '[class.vdnd-droppable-active]': 'isActive()',\n '[class.vdnd-droppable-disabled]': 'disabled()',\n },\n})\nexport class DroppableDirective implements OnDestroy {\n readonly #elementRef = inject(ElementRef<HTMLElement>);\n readonly #dragState = inject(DragStateService);\n readonly #autoScroll = inject(AutoScrollService);\n readonly #positionCalculator = inject(PositionCalculatorService);\n readonly #parentGroup = inject(VDND_GROUP_TOKEN, { optional: true });\n\n /** Unique identifier for this droppable */\n vdndDroppable = input.required<string>();\n\n /**\n * Drag-and-drop group name.\n * Optional when a parent `vdndGroup` directive provides the group context.\n */\n vdndDroppableGroup = input<string>();\n\n /**\n * Resolved group name - uses explicit input or falls back to parent group.\n * Returns null (and disables dropping) if neither is available.\n */\n readonly effectiveGroup = createEffectiveGroupSignal({\n explicitGroup: this.vdndDroppableGroup,\n parentGroup: this.#parentGroup,\n elementId: this.vdndDroppable,\n elementType: 'droppable',\n });\n\n /** Optional data associated with this droppable */\n vdndDroppableData = input<unknown>();\n\n /** Whether this droppable is disabled */\n disabled = input<boolean>(false);\n\n /** Enable auto-scroll when dragging near edges */\n autoScrollEnabled = input<boolean>(true);\n\n /** Auto-scroll configuration */\n autoScrollConfig = input<Partial<AutoScrollConfig>>({});\n\n /** Constrain drag preview and placeholder to container boundaries */\n constrainToContainer = input<boolean>(false);\n\n /** Emits when an item is dropped on this droppable */\n // eslint-disable-next-line @angular-eslint/no-output-native\n drop = output<DropEvent>();\n\n /**\n * Emits each time the placeholder moves within this droppable during a drag\n * (every item displacement) — e.g. to trigger haptic feedback.\n */\n placeholderMove = output<PlaceholderMoveEvent>();\n\n /** Whether this droppable is currently being targeted */\n readonly isActive = computed(() => {\n const activeId = this.#dragState.activeDroppableId();\n return activeId === this.vdndDroppable() && !this.disabled();\n });\n\n /**\n * `END_OF_LIST` while this droppable is active, otherwise null.\n * @deprecated It never identifies an item. For the position, use the `placeholderMove` output\n * (and `DropEvent.destination.index` on drop). Will be removed in the next major version.\n */\n readonly placeholderId = computed(() => {\n if (!this.isActive()) {\n return null;\n }\n return this.#dragState.placeholderId();\n });\n\n /**\n * The placeholder's insertion index in this droppable (DropEvent convention),\n * or null when the placeholder is not here.\n */\n readonly #placeholderInsertionIndex = computed(() => {\n if (!this.isActive() || !this.#dragState.isDragging()) {\n return null;\n }\n const sourceIndex = this.#dragState.sourceIndex();\n return normalizeDropDestinationIndex({\n sourceIndex: sourceIndex ?? -1,\n placeholderIndex: this.#dragState.placeholderIndex(),\n // Without a known source index there is no hidden-source adjustment to undo\n sourceDroppableId: sourceIndex === null ? null : this.#dragState.sourceDroppableId(),\n activeDroppableId: this.vdndDroppable(),\n });\n });\n\n /** Last insertion index reported via placeholderMove (null when not here) */\n #lastPlaceholderIndex: number | null = null;\n\n /** Drag whose initial placeholder position has already been seen by this droppable */\n #placeholderTrackedDrag: DraggedItem | null = null;\n\n /** Track previous active state to detect the drag-end transition */\n #wasActive = false;\n\n /**\n * The terminal drag snapshot this droppable has already processed. `endedDragState`\n * persists until the next drag starts, so this guards against replaying the same drop\n * when the effect re-runs (e.g. `disabled()` toggling) after the drag has ended.\n */\n #handledEndedState: DragState | null = null;\n\n /** Whether this droppable has rendered, so its inputs have values */\n #rendered = false;\n\n constructor() {\n createAutoScrollRegistration({\n autoScrollService: this.#autoScroll,\n getElement: () => this.#elementRef.nativeElement,\n getId: () => this.vdndDroppable(),\n enabled: () => this.autoScrollEnabled(),\n config: () => this.autoScrollConfig(),\n // Register whenever a group is resolved; do NOT gate on scrollability. DOM size is\n // not reactive, so a list that becomes scrollable after init (async data, resize)\n // would never register. AutoScrollService filters by live scroll geometry per drag.\n canRegister: () => Boolean(this.effectiveGroup()),\n });\n\n // Notify the calculator once this droppable is rendered (host data attributes applied).\n // Matters when it mounts DURING an active drag — the candidate snapshot was frozen at\n // drag start, so without this a conditionally rendered list would never become a target.\n afterNextRender(() => {\n this.#rendered = true;\n const group = this.effectiveGroup();\n if (group) {\n this.#positionCalculator.notifyCandidatesChanged(group);\n }\n });\n\n effect(() => {\n const currentIndex = this.#placeholderInsertionIndex();\n untracked(() => this.#handlePlaceholderMove(currentIndex));\n });\n\n // React to state changes and handle drop events.\n //\n // Keyed only on the low-frequency fields (isActive/isDragging/draggedItem). The final\n // placeholder/index values #handleDrop needs are captured by DragStateService.endDrag()\n // into endedDragState() at the drag-end boundary, so this effect never has to poll the\n // high-frequency cursor/placeholder signals — reading them here would make it re-run and\n // re-allocate a snapshot on every 60fps frame, defeating the service's signal splitting.\n effect(() => {\n const active = this.isActive();\n const draggedItem = this.#dragState.draggedItem();\n const isDragging = this.#dragState.isDragging();\n\n // Handle drag end (drop). This droppable is the release target when it was either\n // observed active during the drag (#wasActive) OR named as the target in the ended\n // drag snapshot. The snapshot path covers the pointer-up flush, where the final\n // position is processed and the state cleared in the same synchronous task, so this\n // effect never observes isActive() === true mid-drag and #wasActive stays false.\n const endedState = untracked(() => this.#dragState.endedDragState());\n const endedTargetedThis = endedState?.activeDroppableId === this.vdndDroppable();\n\n if (!isDragging && draggedItem === null && (this.#wasActive || endedTargetedThis)) {\n // Consume each terminal snapshot exactly once. endedDragState persists until the\n // next drag starts and disabled()/other inputs re-run this effect, so without a\n // per-snapshot guard a later state change would replay the same historical drop.\n if (endedState !== this.#handledEndedState) {\n this.#handledEndedState = endedState;\n // Emit only for an enabled target that ended normally. A target disabled at\n // release still consumes the snapshot (so re-enabling can't resurrect the drop)\n // but emits nothing, keeping dragEnd and drop consistent.\n if (!this.disabled() && !this.#dragState.wasCancelled()) {\n this.#handleDrop();\n }\n }\n }\n\n this.#wasActive = active;\n });\n }\n\n ngOnDestroy(): void {\n // Destroyed before it rendered: its inputs may have no values yet, and it never became a\n // drop target or a candidate the calculator knows about. (Not an ngOnInit flag: a subclass\n // with its own ngOnInit would skip it.)\n if (!this.#rendered) {\n return;\n }\n\n // Clean up if this droppable is destroyed while being active\n if (this.isActive()) {\n this.#dragState.setActiveDroppable(null);\n }\n\n // Auto-scroll unregisters itself on destroy (see createAutoScrollRegistration).\n\n // If this droppable unmounts mid-drag, tell the calculator so it drops it from the\n // frozen candidate list (deferred re-query runs once the element has left the DOM).\n const group = untracked(() => this.effectiveGroup());\n if (group) {\n this.#positionCalculator.notifyCandidatesChanged(group);\n }\n }\n\n /**\n * Emit placeholderMove when the placeholder moved within (or entered) this droppable.\n */\n #handlePlaceholderMove(currentIndex: number | null): void {\n let previousIndex = this.#lastPlaceholderIndex;\n this.#lastPlaceholderIndex = currentIndex;\n\n const draggedItem = this.#dragState.draggedItem();\n if (currentIndex === null || currentIndex === previousIndex || !draggedItem) {\n return;\n }\n\n // The drag's first placement in the source list starts from the item's own slot:\n // nothing is displaced when the placeholder simply takes the hidden item's place.\n const isFirstPlacement = this.#placeholderTrackedDrag !== draggedItem;\n this.#placeholderTrackedDrag = draggedItem;\n const sourceDroppableId = this.#dragState.sourceDroppableId();\n const sourceIndex = this.#dragState.sourceIndex();\n if (isFirstPlacement && sourceDroppableId === this.vdndDroppable() && sourceIndex !== null) {\n if (currentIndex === sourceIndex) {\n return;\n }\n previousIndex = sourceIndex;\n }\n\n this.placeholderMove.emit({\n draggableId: draggedItem.draggableId,\n sourceDroppableId: sourceDroppableId ?? '',\n droppableId: this.vdndDroppable(),\n previousIndex,\n currentIndex,\n data: draggedItem.data,\n });\n }\n\n /**\n * Handle a drop on this droppable.\n */\n #handleDrop(): void {\n // The live state is cleared before this effect fires, so read the terminal snapshot\n // captured by endDrag()/cancelDrag() immediately before the reset.\n const state = untracked(() => this.#dragState.endedDragState());\n\n if (!state?.draggedItem || state.activeDroppableId !== this.vdndDroppable()) {\n return;\n }\n\n const sourceDroppableId = state.sourceDroppableId ?? '';\n const placeholderId = state.placeholderId ?? END_OF_LIST;\n\n // Use the stored source index from drag state\n // This is critical for virtual scrolling where the original element may no longer\n // be in the DOM after autoscroll (it gets virtualized out of view)\n const sourceIndex =\n state.sourceIndex ?? this.#getItemIndex(state.draggedItem.draggableId, sourceDroppableId);\n\n // Use the pre-calculated placeholderIndex if available (more reliable)\n // Fall back to DOM-based calculation if not. Then normalize to the same\n // consumer-facing insertion index emitted by DragEndEvent.\n const placeholderIndex =\n state.placeholderIndex !== null && state.placeholderIndex !== undefined\n ? state.placeholderIndex\n : this.#getDestinationIndex(placeholderId);\n const destinationIndex = normalizeDropDestinationIndex({\n sourceIndex,\n placeholderIndex,\n sourceDroppableId,\n activeDroppableId: this.vdndDroppable(),\n });\n\n this.drop.emit({\n source: {\n draggableId: state.draggedItem.draggableId,\n droppableId: sourceDroppableId,\n index: sourceIndex,\n data: state.draggedItem.data,\n },\n destination: {\n droppableId: this.vdndDroppable(),\n placeholderId,\n index: destinationIndex,\n data: this.vdndDroppableData(),\n },\n });\n }\n\n /**\n * Get the index of an item in a droppable.\n * This is a simplified implementation - in practice, the consumer would track this.\n */\n #getItemIndex(draggableId: string, droppableId: string): number {\n // Find all draggables in the source droppable\n const droppable = queryByAttribute<HTMLElement>(document, 'data-droppable-id', droppableId);\n if (!droppable) {\n return 0;\n }\n\n const draggables = droppable.querySelectorAll('[data-draggable-id]');\n for (let i = 0; i < draggables.length; i++) {\n if (draggables[i].getAttribute('data-draggable-id') === draggableId) {\n return i;\n }\n }\n\n return 0;\n }\n\n /**\n * Get the destination index based on the placeholder.\n */\n #getDestinationIndex(placeholderId: string): number {\n // Exclude placeholder elements from the count\n const draggables = this.#elementRef.nativeElement.querySelectorAll(\n '[data-draggable-id]:not([data-draggable-id=\"placeholder\"])',\n );\n\n if (placeholderId === END_OF_LIST) {\n return draggables.length;\n }\n\n // Find the index of the placeholder item\n for (let i = 0; i < draggables.length; i++) {\n if (draggables[i].getAttribute('data-draggable-id') === placeholderId) {\n return i;\n }\n }\n\n return 0;\n }\n\n /**\n * Get the element reference (for external use).\n */\n getElement(): HTMLElement {\n return this.#elementRef.nativeElement;\n }\n\n /**\n * Manually scroll this droppable.\n */\n scrollBy(delta: number): void {\n this.#elementRef.nativeElement.scrollTop += delta;\n }\n\n /**\n * Get the current scroll position.\n */\n getScrollTop(): number {\n return this.#elementRef.nativeElement.scrollTop;\n }\n\n /**\n * Get the scroll height.\n */\n getScrollHeight(): number {\n return this.#elementRef.nativeElement.scrollHeight;\n }\n}\n","import { ChangeDetectionStrategy, Component, input, output, TemplateRef } from '@angular/core';\nimport {\n VirtualScrollContainerComponent,\n VirtualScrollItemContext,\n} from './virtual-scroll-container.component';\nimport { DroppableDirective } from '../directives/droppable.directive';\nimport { AutoScrollConfig } from '../services/auto-scroll.service';\nimport { DropEvent, PlaceholderMoveEvent } from '../models/drag-drop.models';\n\n/**\n * A high-level component that combines droppable, virtual scroll, and placeholder\n * functionality into a single, easy-to-use component.\n *\n * This component significantly reduces boilerplate by automatically handling:\n * - Placeholder insertion at the correct position\n * - Sticky item management for the dragged item\n * - Virtual scrolling with proper drag-and-drop integration\n * - Droppable container setup\n *\n * @example\n * ```html\n * <!-- Before (verbose): ~45 lines of boilerplate -->\n * <div vdndDroppable=\"list-1\" vdndDroppableGroup=\"demo\" (drop)=\"onDrop($event)\">\n * <vdnd-virtual-scroll\n * [items]=\"itemsWithPlaceholder()\"\n * [itemHeight]=\"50\"\n * [stickyItemIds]=\"stickyIds()\"\n * [itemIdFn]=\"getItemId\"\n * [trackByFn]=\"trackById\"\n * [itemTemplate]=\"itemTpl\">\n * </vdnd-virtual-scroll>\n * </div>\n *\n * <!-- After (concise): ~8 lines -->\n * <div vdndGroup=\"demo\">\n * <vdnd-sortable-list\n * droppableId=\"list-1\"\n * [items]=\"list()\"\n * [itemHeight]=\"50\"\n * [itemIdFn]=\"getItemId\"\n * [itemTemplate]=\"itemTpl\"\n * (drop)=\"onDrop($event)\">\n * </vdnd-sortable-list>\n * </div>\n * ```\n */\n@Component({\n selector: 'vdnd-sortable-list',\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [VirtualScrollContainerComponent, DroppableDirective],\n host: {\n class: 'vdnd-sortable-list',\n },\n template: `\n <div\n class=\"vdnd-sortable-list-droppable\"\n [vdndDroppable]=\"droppableId()\"\n [vdndDroppableGroup]=\"group()\"\n [vdndDroppableData]=\"droppableData()\"\n [disabled]=\"disabled()\"\n [constrainToContainer]=\"constrainToContainer()\"\n (drop)=\"drop.emit($event)\"\n (placeholderMove)=\"placeholderMove.emit($event)\"\n >\n <vdnd-virtual-scroll\n [items]=\"items()\"\n [itemHeight]=\"itemHeight()\"\n [dynamicItemHeight]=\"dynamicItemHeight()\"\n [itemIdFn]=\"itemIdFn()\"\n [trackByFn]=\"trackByFn()\"\n [itemTemplate]=\"itemTemplate()\"\n [droppableId]=\"droppableId()\"\n [autoStickyDraggedItem]=\"true\"\n [containerHeight]=\"containerHeight()\"\n [overscan]=\"overscan()\"\n [autoScrollEnabled]=\"autoScrollEnabled()\"\n [autoScrollConfig]=\"autoScrollConfig()\"\n >\n </vdnd-virtual-scroll>\n </div>\n `,\n styles: `\n :host {\n display: block;\n }\n `,\n})\nexport class VirtualSortableListComponent<T> {\n // ========== Required Inputs ==========\n\n /** Unique identifier for this droppable list */\n droppableId = input.required<string>();\n\n /**\n * Drag-and-drop group name.\n * Optional when a parent `vdndGroup` directive provides the group context.\n */\n group = input<string>();\n\n /** Array of items to render */\n items = input.required<T[]>();\n\n /** Height of each item in pixels (used as estimate in dynamic mode) */\n itemHeight = input.required<number>();\n\n /**\n * Enable dynamic item height mode.\n * When true, items are auto-measured via ResizeObserver and `itemHeight`\n * serves as the initial estimate for unmeasured items.\n */\n dynamicItemHeight = input<boolean>(false);\n\n /** Function to get a unique ID from an item */\n itemIdFn = input.required<(item: T) => string>();\n\n /** Template for rendering each item */\n itemTemplate = input.required<TemplateRef<VirtualScrollItemContext<T>>>();\n\n // ========== Optional Inputs ==========\n\n /**\n * Track-by function for the @for loop.\n * Optional - if not provided, will be derived from itemIdFn.\n */\n trackByFn = input<(index: number, item: T) => string | number>();\n\n /** Optional data associated with this droppable */\n droppableData = input<unknown>();\n\n /** Whether this sortable list is disabled */\n disabled = input<boolean>(false);\n\n /**\n * Height of the container in pixels.\n * If not provided, uses CSS-based height detection.\n */\n containerHeight = input<number>();\n\n /** Number of items to render above/below the visible area */\n overscan = input<number>(3);\n\n /** Enable auto-scroll when dragging near edges */\n autoScrollEnabled = input<boolean>(true);\n\n /** Auto-scroll configuration */\n autoScrollConfig = input<Partial<AutoScrollConfig>>({});\n\n /** Constrain drag preview and placeholder to container boundaries */\n constrainToContainer = input<boolean>(false);\n\n // ========== Outputs ==========\n\n /** Emits when an item is dropped on this list */\n // eslint-disable-next-line @angular-eslint/no-output-native\n drop = output<DropEvent>();\n\n /** Emits each time the placeholder moves within this list (every item displacement) */\n placeholderMove = output<PlaceholderMoveEvent>();\n}\n","import {\n ChangeDetectionStrategy,\n Component,\n computed,\n ElementRef,\n inject,\n input,\n NgZone,\n OnDestroy,\n OnInit,\n signal,\n} from '@angular/core';\nimport {\n VDND_OFFSET_ROWS_VIEWPORT,\n VDND_VIRTUAL_VIEWPORT,\n VdndVirtualViewport,\n} from '../tokens/virtual-viewport.token';\nimport { VDND_SCROLL_CONTAINER, VdndScrollContainer } from '../tokens/scroll-container.token';\nimport { AutoScrollConfig, AutoScrollService } from '../services/auto-scroll.service';\nimport {\n bindRafThrottledScrollTopSignal,\n bindResizeObserverHeightSignal,\n} from '../utils/dom-signal-bindings';\nimport { createAutoScrollRegistration } from '../utils/auto-scroll-registration';\nimport type { VirtualScrollStrategy } from '../models/virtual-scroll-strategy';\nimport { FixedHeightStrategy } from '../strategies/fixed-height.strategy';\nimport { DynamicHeightStrategy } from '../strategies/dynamic-height.strategy';\n\n/**\n * A virtual viewport component that provides efficient wrapper-based positioning\n * for virtual scrolling. This component acts as the scroll container and provides\n * a content wrapper with GPU-accelerated transform positioning.\n *\n * Use this component when you need virtual scrolling with optimal performance.\n * Items rendered inside via `*vdndVirtualFor` will be positioned using a single\n * transform on the wrapper, rather than individual absolute positioning.\n *\n * @example\n * Basic usage:\n * ```html\n * <vdnd-virtual-viewport [itemHeight]=\"50\" style=\"height: 400px;\">\n * <ng-container *vdndVirtualFor=\"let item of items(); trackBy: trackById\">\n * <div class=\"item\">{{ item.name }}</div>\n * </ng-container>\n * </vdnd-virtual-viewport>\n * ```\n *\n * @example\n * With dynamic item heights:\n * ```html\n * <vdnd-virtual-viewport\n * [itemHeight]=\"50\"\n * [dynamicItemHeight]=\"true\"\n * style=\"height: 400px;\">\n * <ng-container *vdndVirtualFor=\"let item of items(); trackBy: trackById\">\n * <div class=\"item\">{{ item.name }}</div>\n * </ng-container>\n * </vdnd-virtual-viewport>\n * ```\n */\n@Component({\n selector: 'vdnd-virtual-viewport',\n changeDetection: ChangeDetectionStrategy.OnPush,\n providers: [\n { provide: VDND_VIRTUAL_VIEWPORT, useExisting: VirtualViewportComponent },\n { provide: VDND_OFFSET_ROWS_VIEWPORT, useExisting: VirtualViewportComponent },\n { provide: VDND_SCROLL_CONTAINER, useExisting: VirtualViewportComponent },\n ],\n host: {\n class: 'vdnd-virtual-viewport',\n // Read by the drag index calculator: this element scrolls its own rows, which start\n // data-content-offset px below the top of the scroll area\n 'data-virtual-viewport': '',\n '[attr.data-content-offset]': 'contentOffset()',\n },\n styles: `\n :host {\n display: block;\n overflow: auto;\n position: relative;\n /* Disable browser scroll anchoring to prevent scroll position adjustments\n when DOM changes (e.g., placeholder position updates during drag) */\n overflow-anchor: none;\n }\n\n .vdnd-viewport-spacer {\n position: absolute;\n left: 0;\n width: 1px;\n visibility: hidden;\n pointer-events: none;\n }\n\n .vdnd-viewport-content {\n position: absolute;\n left: 0;\n right: 0;\n will-change: transform;\n }\n `,\n template: `\n <!-- Spacer maintains total scroll height -->\n <div\n class=\"vdnd-viewport-spacer\"\n [style.top.px]=\"contentOffset()\"\n [style.height.px]=\"totalHeight()\"\n ></div>\n\n <!-- Content wrapper with GPU-accelerated transform -->\n <div\n class=\"vdnd-viewport-content\"\n [style.top.px]=\"contentOffset()\"\n [style.transform]=\"contentTransform()\"\n >\n <ng-content></ng-content>\n </div>\n `,\n})\nexport class VirtualViewportComponent\n implements VdndVirtualViewport, VdndScrollContainer, OnInit, OnDestroy\n{\n readonly #elementRef = inject(ElementRef<HTMLElement>);\n readonly #ngZone = inject(NgZone);\n readonly #autoScrollService = inject(AutoScrollService);\n\n /** Current scroll position (reactive) */\n readonly #scrollTop = signal(0);\n\n /** Measured container height (reactive) */\n readonly #containerHeight = signal(0);\n\n /** Cleanup function for scroll listener */\n #scrollCleanup: (() => void) | null = null;\n #resizeCleanup: (() => void) | null = null;\n\n /** Generated ID for auto-scroll registration */\n #generatedScrollId = `vdnd-viewport-${Math.random().toString(36).slice(2, 9)}`;\n\n /**\n * The actual first rendered item index, set by VirtualForDirective.\n * This accounts for overscan and is used for wrapper positioning.\n */\n readonly #renderStartIndex = signal(0);\n\n // ========== Inputs ==========\n\n /** Height of each item in pixels (used as estimate in dynamic mode) */\n itemHeight = input.required<number>();\n\n /**\n * Enable dynamic item height mode.\n * When true, items are auto-measured via ResizeObserver and `itemHeight`\n * serves as the initial estimate for unmeasured items.\n */\n dynamicItemHeight = input<boolean>(false);\n\n /** Offset for content below headers (in pixels) */\n contentOffset = input<number>(0);\n\n /** Unique ID for this scroll container (used for auto-scroll registration) */\n scrollContainerId = input<string>();\n\n /** Whether auto-scroll is enabled when dragging near edges */\n autoScrollEnabled = input<boolean>(true);\n\n /** Auto-scroll configuration */\n autoScrollConfig = input<Partial<AutoScrollConfig>>({});\n\n // ========== Strategy ==========\n\n /** The virtual scroll strategy, created based on dynamicItemHeight input */\n readonly #strategy = computed<VirtualScrollStrategy>(() => {\n const height = this.itemHeight();\n return this.dynamicItemHeight()\n ? new DynamicHeightStrategy(height)\n : new FixedHeightStrategy(height);\n });\n\n get strategy(): VirtualScrollStrategy {\n return this.#strategy();\n }\n\n // ========== Computed Values ==========\n\n /** Total height of all items (for scroll height), derived from strategy item count */\n readonly totalHeight = computed(() => {\n const s = this.#strategy();\n s.version();\n return s.getTotalHeight(s.getItemCount());\n });\n\n /** Transform for content wrapper positioning */\n readonly contentTransform = computed(() => {\n const startIndex = this.#renderStartIndex();\n const s = this.#strategy();\n s.version();\n const offset = s.getOffsetForIndex(startIndex);\n return `translateY(${offset}px)`;\n });\n\n // ========== VdndVirtualViewport Implementation ==========\n\n scrollTop(): number {\n return this.#scrollTop();\n }\n\n containerHeight(): number {\n return this.#containerHeight();\n }\n\n get nativeElement(): HTMLElement {\n return this.#elementRef.nativeElement;\n }\n\n /**\n * Called by VirtualForDirective to inform this viewport of the actual\n * first rendered item index. Used for wrapper positioning.\n */\n setRenderStartIndex(index: number): void {\n this.#renderStartIndex.set(index);\n }\n\n getOffsetForIndex(index: number): number {\n return this.#strategy().getOffsetForIndex(index);\n }\n\n // ========== VdndScrollContainer Implementation ==========\n\n scrollTo(options: ScrollToOptions): void {\n this.nativeElement.scrollTo(options);\n }\n\n scrollBy(delta: number): void {\n const newPosition = Math.max(\n 0,\n Math.min(\n this.scrollTop() + delta,\n this.nativeElement.scrollHeight - this.nativeElement.clientHeight,\n ),\n );\n this.scrollTo({ top: newPosition });\n }\n\n // ========== Lifecycle ==========\n\n constructor() {\n createAutoScrollRegistration({\n autoScrollService: this.#autoScrollService,\n getElement: () => this.nativeElement,\n getId: () => this.scrollContainerId() ?? this.#generatedScrollId,\n enabled: () => this.autoScrollEnabled(),\n config: () => this.autoScrollConfig(),\n });\n }\n\n ngOnInit(): void {\n this.#setupScrollListener();\n this.#setupResizeObserver();\n }\n\n ngOnDestroy(): void {\n this.#scrollCleanup?.();\n this.#resizeCleanup?.();\n }\n\n // ========== Private Methods ==========\n\n /** Minimum scroll delta (px) to trigger signal update */\n readonly #scrollThreshold = 5;\n\n #setupScrollListener(): void {\n this.#scrollCleanup = bindRafThrottledScrollTopSignal({\n element: this.nativeElement,\n ngZone: this.#ngZone,\n scrollTop: this.#scrollTop,\n thresholdPx: this.#scrollThreshold,\n });\n }\n\n #setupResizeObserver(): void {\n this.#resizeCleanup = bindResizeObserverHeightSignal({\n element: this.nativeElement,\n ngZone: this.#ngZone,\n height: this.#containerHeight,\n minDeltaPx: 1,\n });\n }\n}\n","import { Directive, ElementRef, inject } from '@angular/core';\n\n/**\n * Marks an element as the header content for a `vdnd-virtual-content` component.\n *\n * Place this directive on a projected element inside `<vdnd-virtual-content>`.\n * The component will automatically measure the header's height via ResizeObserver\n * and use it as the content offset for virtual scroll calculations.\n *\n * This eliminates the need for manual ResizeObserver boilerplate that was\n * previously required with the `[contentOffset]` input.\n *\n * @example\n * ```html\n * <vdnd-virtual-content [itemHeight]=\"50\">\n * <div class=\"page-header\" vdndContentHeader>\n * <h1>My List</h1>\n * </div>\n * <ng-container *vdndVirtualFor=\"let item of items(); trackBy: trackById\">\n * <div>{{ item.name }}</div>\n * </ng-container>\n * </vdnd-virtual-content>\n * ```\n */\n@Directive({\n selector: '[vdndContentHeader]',\n})\nexport class ContentHeaderDirective {\n readonly elementRef = inject(ElementRef<HTMLElement>);\n}\n","import {\n ChangeDetectionStrategy,\n Component,\n computed,\n contentChild,\n effect,\n ElementRef,\n inject,\n input,\n NgZone,\n PLATFORM_ID,\n signal,\n} from '@angular/core';\nimport { isPlatformBrowser } from '@angular/common';\nimport { VDND_VIRTUAL_VIEWPORT, VdndVirtualViewport } from '../tokens/virtual-viewport.token';\nimport { VDND_SCROLL_CONTAINER, VdndScrollContainer } from '../tokens/scroll-container.token';\nimport type { VirtualScrollStrategy } from '../models/virtual-scroll-strategy';\nimport { FixedHeightStrategy } from '../strategies/fixed-height.strategy';\nimport { DynamicHeightStrategy } from '../strategies/dynamic-height.strategy';\nimport { ContentHeaderDirective } from '../directives/content-header.directive';\n\n/**\n * A virtual content component that provides wrapper-based positioning\n * for virtual scrolling within an EXTERNAL scroll container.\n *\n * Use this component when you need virtual scrolling alongside other content\n * (headers, footers) within a shared scroll container. The component provides\n * a content wrapper with GPU-accelerated transform positioning while delegating\n * scroll handling to the parent `vdndScrollable` container.\n *\n * Headers marked with `vdndContentHeader` are automatically measured via\n * ResizeObserver — no manual offset calculation needed.\n *\n * @example\n * Content projection with auto-measured header:\n * ```html\n * <div vdndScrollable style=\"overflow: auto; height: 100vh;\">\n * <vdnd-virtual-content [itemHeight]=\"50\">\n * <div class=\"header\" vdndContentHeader>Welcome!</div>\n * <ng-container *vdndVirtualFor=\"let item of items(); trackBy: trackById\">\n * <div class=\"item\">{{ item.name }}</div>\n * </ng-container>\n * </vdnd-virtual-content>\n * </div>\n * ```\n *\n * @example\n * Manual offset (escape hatch):\n * ```html\n * <div vdndScrollable style=\"overflow: auto; height: 100vh;\">\n * <div class=\"header\" #header>Welcome!</div>\n * <vdnd-virtual-content [itemHeight]=\"50\" [contentOffset]=\"header.offsetHeight\">\n * <ng-container *vdndVirtualFor=\"let item of items(); trackBy: trackById\">\n * <div class=\"item\">{{ item.name }}</div>\n * </ng-container>\n * </vdnd-virtual-content>\n * </div>\n * ```\n */\n@Component({\n selector: 'vdnd-virtual-content',\n changeDetection: ChangeDetectionStrategy.OnPush,\n providers: [\n { provide: VDND_VIRTUAL_VIEWPORT, useExisting: VirtualContentComponent },\n { provide: VDND_SCROLL_CONTAINER, useExisting: VirtualContentComponent },\n ],\n host: {\n class: 'vdnd-virtual-content',\n '[attr.data-content-offset]': 'effectiveContentOffset()',\n '[attr.data-item-height]': 'itemHeight()',\n '[attr.data-total-items]': 'totalItems()',\n },\n styles: `\n :host {\n display: block;\n position: relative;\n }\n\n .vdnd-virtual-area {\n position: relative;\n }\n\n .vdnd-content-spacer {\n position: absolute;\n top: 0;\n left: 0;\n width: 1px;\n visibility: hidden;\n pointer-events: none;\n }\n\n .vdnd-content-wrapper {\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n will-change: transform;\n }\n `,\n template: `\n <!-- Projected header — in normal document flow, auto-measured via ResizeObserver -->\n <ng-content select=\"[vdndContentHeader]\" />\n\n <!-- Virtual area — sized to totalHeight, contains absolute-positioned spacer + wrapper -->\n <div class=\"vdnd-virtual-area\" [style.height.px]=\"totalHeight()\">\n <!-- Spacer maintains scroll height for the virtual list portion -->\n <div class=\"vdnd-content-spacer\" [style.height.px]=\"totalHeight()\"></div>\n\n <!-- Content wrapper with GPU-accelerated transform -->\n <div class=\"vdnd-content-wrapper\" [style.transform]=\"contentTransform()\">\n <ng-content />\n </div>\n </div>\n `,\n})\nexport class VirtualContentComponent implements VdndVirtualViewport, VdndScrollContainer {\n readonly #elementRef = inject(ElementRef<HTMLElement>);\n readonly #ngZone = inject(NgZone);\n readonly #isBrowser = isPlatformBrowser(inject(PLATFORM_ID));\n\n /**\n * The parent scroll container injected via skip-self to get the actual scrollable element.\n * We provide our own VDND_SCROLL_CONTAINER with adjusted values to children.\n */\n readonly #parentScrollContainer = inject(VDND_SCROLL_CONTAINER, { skipSelf: true });\n\n // ========== Content Queries ==========\n\n /** Projected header directive (if any) */\n private readonly headerDirective = contentChild(ContentHeaderDirective);\n\n // ========== Inputs ==========\n\n /** Height of each item in pixels (used as estimate in dynamic mode) */\n itemHeight = input.required<number>();\n\n /**\n * Offset for content above the virtual list (e.g., header height).\n * When a `vdndContentHeader` is projected, this input is ignored —\n * the offset is auto-measured via ResizeObserver.\n * Use this input only when the header lives outside the component.\n */\n contentOffset = input<number>(0);\n\n /**\n * Enable dynamic item height mode.\n * When true, items are auto-measured via ResizeObserver and `itemHeight`\n * serves as the initial estimate for unmeasured items.\n */\n dynamicItemHeight = input<boolean>(false);\n\n // ========== Internal State ==========\n\n /**\n * The actual first rendered item index, set by VirtualForDirective.\n * This accounts for overscan and is used for wrapper positioning.\n */\n readonly #renderStartIndex = signal(0);\n\n /** Auto-measured header height from ResizeObserver */\n readonly #measuredHeaderHeight = signal(0);\n\n // ========== Strategy ==========\n\n /** The virtual scroll strategy, created based on dynamicItemHeight input */\n readonly #strategy = computed<VirtualScrollStrategy>(() => {\n const height = this.itemHeight();\n return this.dynamicItemHeight()\n ? new DynamicHeightStrategy(height)\n : new FixedHeightStrategy(height);\n });\n\n get strategy(): VirtualScrollStrategy {\n return this.#strategy();\n }\n\n // ========== Computed Values ==========\n\n /** Total item count, derived from strategy (populated by VirtualForDirective) */\n readonly totalItems = computed(() => {\n const s = this.#strategy();\n s.version();\n return s.getItemCount();\n });\n\n /** Total height of all items (for scroll height) */\n readonly totalHeight = computed(() => {\n const s = this.#strategy();\n s.version();\n return s.getTotalHeight(s.getItemCount());\n });\n\n /**\n * Effective content offset: when a `vdndContentHeader` directive is projected,\n * returns the auto-measured header height. Otherwise falls back to the\n * `contentOffset` input for backward compatibility.\n */\n readonly effectiveContentOffset = computed(() => {\n const header = this.headerDirective();\n return header ? this.#measuredHeaderHeight() : this.contentOffset();\n });\n\n /**\n * Adjusted scroll position - subtracts the content offset so the virtual scroll\n * calculates visible items correctly relative to where the list starts.\n */\n readonly #adjustedScrollTop = computed(() => {\n return Math.max(0, this.#parentScrollContainer.scrollTop() - this.effectiveContentOffset());\n });\n\n /** Transform for content wrapper positioning */\n readonly contentTransform = computed(() => {\n const startIndex = this.#renderStartIndex();\n const s = this.#strategy();\n s.version();\n const offset = s.getOffsetForIndex(startIndex);\n return `translateY(${offset}px)`;\n });\n\n constructor() {\n this.#setupHeaderMeasurement();\n }\n\n // ========== VdndVirtualViewport Implementation ==========\n\n /** Adjusted scroll position relative to the virtual list start */\n scrollTop(): number {\n return this.#adjustedScrollTop();\n }\n\n containerHeight(): number {\n return this.#parentScrollContainer.containerHeight();\n }\n\n get nativeElement(): HTMLElement {\n return this.#elementRef.nativeElement;\n }\n\n /**\n * Called by VirtualForDirective to inform this viewport of the actual\n * first rendered item index. Used for wrapper positioning.\n */\n setRenderStartIndex(index: number): void {\n this.#renderStartIndex.set(index);\n }\n\n getOffsetForIndex(index: number): number {\n return this.#strategy().getOffsetForIndex(index);\n }\n\n // ========== VdndScrollContainer Implementation ==========\n\n /**\n * Scroll to a specific position, adjusting for content offset.\n */\n scrollTo(options: ScrollToOptions): void {\n const adjustedOptions = { ...options };\n if (adjustedOptions.top !== undefined) {\n // Add offset back when scrolling to ensure correct position\n adjustedOptions.top += this.effectiveContentOffset();\n }\n this.#parentScrollContainer.scrollTo(adjustedOptions);\n }\n\n // ========== Private Methods ==========\n\n /**\n * Sets up an effect that observes the projected header directive's element\n * with a ResizeObserver, keeping `#measuredHeaderHeight` in sync.\n */\n #setupHeaderMeasurement(): void {\n effect((onCleanup) => {\n const dir = this.headerDirective();\n if (!dir) {\n this.#measuredHeaderHeight.set(0);\n return;\n }\n\n // Server rendering: no layout to measure, and no ResizeObserver\n if (!this.#isBrowser) {\n return;\n }\n\n const el = dir.elementRef.nativeElement;\n this.#measuredHeaderHeight.set(el.offsetHeight);\n\n let observer: ResizeObserver | null = null;\n this.#ngZone.runOutsideAngular(() => {\n observer = new ResizeObserver((entries) => {\n for (const entry of entries) {\n const height =\n entry.borderBoxSize?.[0]?.blockSize ?? (entry.target as HTMLElement).offsetHeight;\n this.#measuredHeaderHeight.set(height);\n }\n });\n observer.observe(el, { box: 'border-box' });\n });\n\n onCleanup(() => observer?.disconnect());\n });\n }\n}\n","import { afterNextRender, EnvironmentInjector, NgZone } from '@angular/core';\nimport { DragStateService } from '../services/drag-state.service';\nimport { KeyboardDragService } from '../services/keyboard-drag.service';\nimport { PositionCalculatorService } from '../services/position-calculator.service';\nimport { DragIndexCalculatorService } from '../services/drag-index-calculator.service';\nimport { ElementCloneService } from '../services/element-clone.service';\nimport { OverlayContainerService } from '../services/overlay-container.service';\nimport { DragEndEvent, DraggedItem, DragStartEvent } from '../models/drag-drop.models';\nimport { queryByAttribute } from '../utils/attribute-selectors';\nimport { normalizeDropDestinationIndex } from '../utils/drop-index-normalization';\n\n/**\n * Context from the directive needed for keyboard drag operations.\n */\nexport interface KeyboardDragContext {\n element: HTMLElement;\n draggableId: string;\n groupName: string | null;\n data: unknown;\n}\n\n/**\n * Callbacks from the handler back into the directive for events.\n */\nexport interface KeyboardDragCallbacks {\n onDragStart: (event: DragStartEvent) => void;\n onDragEnd: (event: DragEndEvent) => void;\n getParentDroppableId: () => string | null;\n calculateSourceIndex: (element: HTMLElement, droppableElement: HTMLElement | null) => number;\n}\n\n/**\n * Dependencies injected from the directive (non-injectable handler).\n */\nexport interface KeyboardDragDeps {\n dragState: DragStateService;\n keyboardDrag: KeyboardDragService;\n positionCalculator: PositionCalculatorService;\n dragIndexCalculator: DragIndexCalculatorService;\n elementClone: ElementCloneService;\n overlayContainer: OverlayContainerService;\n ngZone: NgZone;\n envInjector: EnvironmentInjector;\n callbacks: KeyboardDragCallbacks;\n getContext: () => KeyboardDragContext;\n}\n\n/**\n * Handles keyboard-initiated drag operations (Space to start, arrows to move, Space/Enter to drop).\n *\n * Extracted from DraggableDirective to encapsulate:\n * - Starting/completing/cancelling keyboard drags\n * - Document-level keyboard listener during active drag\n * - Focus restoration after drag ends\n * - Cross-list movement via arrow keys\n *\n * Provides a unified `handleKey()` method that eliminates the duplicated\n * key→action dispatch that previously existed in both host bindings and\n * a document-level listener.\n */\nexport class KeyboardDragHandler {\n readonly #deps: KeyboardDragDeps;\n #boundKeyDown: ((e: KeyboardEvent) => void) | null = null;\n /**\n * The drag this handler started. Keyboard drag state is shared by every draggable, so a key\n * that reaches another item (one focused by a click during the drag, for example) must not\n * move, drop or cancel this drag in that item's name.\n */\n #ownDrag: DraggedItem | null = null;\n\n constructor(deps: KeyboardDragDeps) {\n this.#deps = deps;\n this.#boundKeyDown = this.#onDocumentKeyDown.bind(this);\n }\n\n /**\n * Whether a keyboard drag this handler started is active.\n */\n isActive(): boolean {\n return (\n this.#ownDrag !== null &&\n this.#deps.keyboardDrag.isActive() &&\n this.#deps.dragState.draggedItem() === this.#ownDrag\n );\n }\n\n /**\n * Start a keyboard drag operation.\n */\n activate(): void {\n const ctx = this.#deps.getContext();\n if (!ctx.groupName) {\n return;\n }\n\n const element = ctx.element;\n const rect = element.getBoundingClientRect();\n\n // Find the parent droppable\n const droppableElement = this.#deps.positionCalculator.getDroppableParent(\n element,\n ctx.groupName,\n );\n if (!droppableElement) {\n return;\n }\n\n const droppableId = this.#deps.positionCalculator.getDroppableId(droppableElement);\n if (!droppableId) {\n return;\n }\n\n // Calculate source index\n const sourceIndex = this.#deps.callbacks.calculateSourceIndex(element, droppableElement);\n\n // Get total item count from the droppable\n const totalItemCount = this.#deps.dragIndexCalculator.getTotalItemCount({\n droppableElement,\n isSameList: false,\n draggedItemHeight: rect.height,\n });\n\n // Clone element BEFORE updating drag state.\n // Template-first: skip the clone when a template-based preview is mounted.\n const clonedElement = this.#deps.overlayContainer.hasTemplatePreview()\n ? undefined\n : this.#deps.elementClone.cloneElement(element);\n\n // Start keyboard drag\n this.#deps.keyboardDrag.startKeyboardDrag(\n {\n draggableId: ctx.draggableId,\n droppableId,\n element,\n clonedElement,\n height: rect.height,\n width: rect.width,\n data: ctx.data,\n },\n sourceIndex,\n totalItemCount,\n droppableId,\n );\n this.#ownDrag = this.#deps.dragState.draggedItem();\n\n // Add document-level keyboard listener (since element is hidden with display:none)\n this.#deps.ngZone.runOutsideAngular(() => {\n document.addEventListener('keydown', this.#boundKeyDown!);\n });\n\n // Emit drag start event\n this.#deps.callbacks.onDragStart({\n draggableId: ctx.draggableId,\n droppableId,\n data: ctx.data,\n position: { x: rect.left, y: rect.top },\n sourceIndex,\n });\n }\n\n /**\n * Unified key dispatch. Returns true if the key was handled.\n * Used by both host bindings and the document-level listener.\n *\n * Handled keys are consumed entirely (preventDefault + stopPropagation): right after pickup\n * the source element can still be focused because Angular has not applied display:none yet,\n * and without stopping propagation the same keydown would be processed by both the element's\n * host binding and the document-level listener — moving the item two positions per press.\n */\n handleKey(event: KeyboardEvent): boolean {\n if (!this.isActive()) {\n return false;\n }\n\n const handled = this.#dispatchKey(event.key);\n\n if (handled) {\n event.preventDefault();\n event.stopPropagation();\n }\n\n return handled;\n }\n\n /**\n * Execute the drag action for a key. Returns true if the key maps to an action.\n */\n #dispatchKey(key: string): boolean {\n switch (key) {\n case ' ': // Space\n case 'Enter':\n this.complete();\n return true;\n case 'Escape':\n case 'Tab':\n this.cancel();\n return true;\n case 'ArrowUp':\n this.#deps.keyboardDrag.moveUp();\n return true;\n case 'ArrowDown':\n this.#deps.keyboardDrag.moveDown();\n return true;\n case 'ArrowLeft':\n this.#moveToAdjacentDroppable('left');\n return true;\n case 'ArrowRight':\n this.#moveToAdjacentDroppable('right');\n return true;\n default:\n return false;\n }\n }\n\n /**\n * Complete a keyboard drag operation (drop the item).\n */\n complete(): void {\n const ctx = this.#deps.getContext();\n const sourceIndex = this.#deps.dragState.sourceIndex() ?? 0;\n const activeDroppableId = this.#deps.dragState.activeDroppableId();\n\n // Revalidate the active target: it may have been disabled after the drag navigated\n // into it. A disabled (or missing) target is not a valid drop — report no destination.\n // The droppable's own disabled guard suppresses the drop event, keeping dragEnd and\n // drop consistent (non-cancelled dragEnd with destinationIndex: null, no drop).\n const hasValidTarget =\n activeDroppableId !== null &&\n !this.#deps.positionCalculator.isDroppableDisabledById(activeDroppableId);\n\n const destinationIndex = hasValidTarget\n ? normalizeDropDestinationIndex({\n sourceIndex,\n placeholderIndex: this.#deps.dragState.placeholderIndex(),\n sourceDroppableId: this.#deps.dragState.sourceDroppableId(),\n activeDroppableId,\n })\n : null;\n\n // Remove document listener\n this.#cleanupDocumentListener();\n\n // Clear droppable metadata cache from this drag session\n this.#deps.dragIndexCalculator.clearCache();\n\n // Emit drag end event\n this.#deps.callbacks.onDragEnd({\n draggableId: ctx.draggableId,\n droppableId: this.#deps.callbacks.getParentDroppableId() ?? '',\n cancelled: false,\n data: ctx.data,\n sourceIndex,\n destinationIndex,\n });\n\n // The item stays in its source list when there is no valid target\n const fallbackDroppableId = hasValidTarget\n ? activeDroppableId\n : this.#deps.dragState.sourceDroppableId();\n\n this.#deps.keyboardDrag.completeKeyboardDrag();\n\n // Restore focus to the moved element after state updates\n this.#restoreFocus(ctx.draggableId, fallbackDroppableId);\n }\n\n /**\n * Cancel a keyboard drag operation.\n */\n cancel(): void {\n const ctx = this.#deps.getContext();\n const sourceIndex = this.#deps.dragState.sourceIndex() ?? 0;\n // A cancelled item goes back to its source list\n const sourceDroppableId = this.#deps.dragState.sourceDroppableId();\n\n // Remove document listener\n this.#cleanupDocumentListener();\n\n // Clear droppable metadata cache from this drag session\n this.#deps.dragIndexCalculator.clearCache();\n\n // Emit drag end event\n this.#deps.callbacks.onDragEnd({\n draggableId: ctx.draggableId,\n droppableId: this.#deps.callbacks.getParentDroppableId() ?? '',\n cancelled: true,\n data: ctx.data,\n sourceIndex,\n destinationIndex: null,\n });\n\n this.#deps.keyboardDrag.cancelKeyboardDrag();\n\n // Restore focus to the original element after state updates\n this.#restoreFocus(ctx.draggableId, sourceDroppableId);\n }\n\n /**\n * Teardown — remove any active document listener.\n */\n destroy(): void {\n this.#cleanupDocumentListener();\n }\n\n /**\n * Restore focus to the dragged element after keyboard drag ends.\n * Uses afterNextRender to ensure Angular has finished updating the DOM\n * (element is no longer hidden after isDragging() becomes false).\n *\n * Uses EnvironmentInjector to ensure callback runs even if the directive\n * is destroyed during cross-list moves.\n *\n * `fallbackDroppableId` is the list whose first draggable gets focus when the element is not\n * rendered (for example scrolled out of a virtual list). Callers read it before ending the\n * drag, which clears the drag state.\n */\n #restoreFocus(draggableId: string, fallbackDroppableId: string | null): void {\n afterNextRender(\n () => {\n const element = queryByAttribute<HTMLElement>(document, 'data-draggable-id', draggableId);\n\n if (element) {\n element.focus();\n } else if (fallbackDroppableId) {\n // Fallback: focus the first draggable in the list the item ended up in\n const container = queryByAttribute<HTMLElement>(\n document,\n 'data-droppable-id',\n fallbackDroppableId,\n );\n const firstDraggable = container?.querySelector<HTMLElement>('[data-draggable-id]');\n firstDraggable?.focus();\n }\n },\n { injector: this.#deps.envInjector },\n );\n }\n\n /**\n * Move to an adjacent droppable in the specified direction.\n */\n #moveToAdjacentDroppable(direction: 'left' | 'right'): void {\n const currentDroppableId = this.#deps.dragState.activeDroppableId();\n if (!currentDroppableId) {\n return;\n }\n\n const groupName = this.#deps.getContext().groupName;\n if (!groupName) {\n return;\n }\n const adjacent = this.#deps.positionCalculator.findAdjacentDroppable(\n currentDroppableId,\n direction,\n groupName,\n );\n\n if (!adjacent) {\n return;\n }\n\n // Derive the destination list's item count from DragIndexCalculatorService — the single\n // source of truth that correctly handles registered strategies, dynamic-height lists, and\n // vdnd-virtual-content (page-scroll) lists. Arrowing back to the origin lands on the source\n // list, so compute isSameList rather than assuming a distinct target.\n const itemCount = this.#deps.dragIndexCalculator.getTotalItemCount({\n droppableElement: adjacent.element,\n isSameList: adjacent.id === this.#deps.dragState.sourceDroppableId(),\n draggedItemHeight: this.#deps.dragState.draggedItem()?.height ?? 0,\n });\n\n // Maintain the current target index (clamped to the new list's size)\n const currentTargetIndex = this.#deps.keyboardDrag.targetIndex() ?? 0;\n const targetIndex = Math.min(currentTargetIndex, itemCount);\n\n this.#deps.keyboardDrag.moveToDroppable(adjacent.id, targetIndex, itemCount);\n }\n\n /**\n * Document-level keydown listener active during keyboard drag.\n */\n #onDocumentKeyDown(event: KeyboardEvent): void {\n // The drag ended without this handler (its state was reset elsewhere): stop listening, or\n // this listener would also take the keys of the next keyboard drag\n if (!this.isActive()) {\n this.#cleanupDocumentListener();\n return;\n }\n this.handleKey(event);\n }\n\n /**\n * Remove the document-level keyboard listener.\n */\n #cleanupDocumentListener(): void {\n this.#ownDrag = null;\n // Server rendering destroys the directive without a global document, and never added it\n if (this.#boundKeyDown && typeof document !== 'undefined') {\n document.removeEventListener('keydown', this.#boundKeyDown);\n }\n }\n}\n","/**\n * Elements inside a draggable that keep their own interaction: pressing one never starts a\n * pointer drag, and Space pressed on one never starts a keyboard drag.\n */\nexport const INTERACTIVE_ELEMENT_SELECTOR = 'button, input, textarea, select, [contenteditable]';\n\n/** Class that excludes the element carrying it, and everything inside it, from starting a drag. */\nexport const NO_DRAG_CLASS = 'no-drag';\n\n/**\n * The `no-drag` element inside `draggable` (the draggable itself included) that contains\n * `target`, or null. A `no-drag` ancestor of the draggable does not count.\n */\nexport function findNoDragElement(target: Element, draggable: Element): Element | null {\n const noDrag = target.closest(`.${NO_DRAG_CLASS}`);\n return noDrag !== null && draggable.contains(noDrag) ? noDrag : null;\n}\n","import { NgZone } from '@angular/core';\nimport { CursorPosition } from '../models/drag-drop.models';\nimport { findNoDragElement, INTERACTIVE_ELEMENT_SELECTOR } from '../utils/interactive-elements';\n\n/**\n * Callbacks from the handler back into the directive for drag lifecycle.\n */\nexport interface PointerDragCallbacks {\n onDragStart: (position: CursorPosition) => void;\n onDragMove: (position: CursorPosition) => void;\n onDragEnd: (cancelled: boolean) => void;\n onPendingChange: (pending: boolean) => void;\n isDragging: () => boolean;\n /** Whether a drag of another item (pointer or keyboard) is in progress. */\n isOtherDragActive: () => boolean;\n}\n\n/**\n * Context from the directive needed for pointer drag operations.\n */\nexport interface PointerDragContext {\n element: HTMLElement;\n groupName: string | null;\n disabled: boolean;\n dragHandle: string | undefined;\n dragThreshold: number;\n dragDelay: number;\n}\n\n/**\n * Dependencies injected from the directive (non-injectable handler).\n */\nexport interface PointerDragDeps {\n ngZone: NgZone;\n callbacks: PointerDragCallbacks;\n getContext: () => PointerDragContext;\n}\n\n/**\n * Handles pointer-based (mouse + touch) drag operations.\n *\n * Extracted from DraggableDirective to encapsulate:\n * - Pointer down / move / up lifecycle\n * - Drag threshold detection\n * - Drag delay timer\n * - Forwarding moves to the directive (DragSchedulerService coalesces them per frame)\n * - Document-level listener management\n * - Escape key cancellation during pointer drag, and cancellation when the window loses focus\n * or the page is hidden (the release would never arrive) or the system cancels the touch\n */\nexport class PointerDragHandler {\n readonly #deps: PointerDragDeps;\n\n /** Starting position of the drag */\n #startPosition: CursorPosition | null = null;\n\n /** Whether we're currently tracking a potential drag */\n #isTracking = false;\n\n /** Identifier of the finger that pressed, for touch gestures (other fingers are ignored) */\n #touchId: number | null = null;\n\n /** Bound event handlers for cleanup */\n #boundPointerMove: ((e: MouseEvent | TouchEvent) => void) | null = null;\n #boundPointerUp: ((e: MouseEvent | TouchEvent) => void) | null = null;\n #boundKeyDown: ((e: KeyboardEvent) => void) | null = null;\n #boundWindowBlur: (() => void) | null = null;\n #boundVisibilityChange: (() => void) | null = null;\n\n /** Timer ID for drag delay */\n #delayTimerId: ReturnType<typeof setTimeout> | null = null;\n\n /** Whether the delay has been satisfied (user held long enough) */\n #delayReady = false;\n\n constructor(deps: PointerDragDeps) {\n this.#deps = deps;\n this.#boundPointerMove = this.#onPointerMove.bind(this);\n this.#boundPointerUp = this.#onPointerUp.bind(this);\n this.#boundKeyDown = this.#onEscapeKeyDown.bind(this);\n this.#boundWindowBlur = this.#onFocusLost.bind(this);\n this.#boundVisibilityChange = this.#onVisibilityChange.bind(this);\n }\n\n /**\n * The position where the user initially pressed down.\n * Used by the directive to calculate grab offset when starting drag.\n */\n getStartPosition(): CursorPosition | null {\n return this.#startPosition;\n }\n\n /**\n * Handle pointer down (mouse or touch).\n * Called from the directive's host binding.\n */\n onPointerDown(event: MouseEvent | TouchEvent, isTouch: boolean): void {\n const ctx = this.#deps.getContext();\n\n if (ctx.disabled) {\n return;\n }\n\n // Without a group, this draggable can't participate in DnD (fail gracefully).\n if (!ctx.groupName) {\n return;\n }\n\n // Check for left mouse button only\n if (!isTouch && (event as MouseEvent).button !== 0) {\n return;\n }\n\n // Check if click is on drag handle (if specified)\n if (ctx.dragHandle) {\n const target = event.target as HTMLElement;\n if (!target.closest(ctx.dragHandle)) {\n return;\n }\n }\n\n // Check for elements that should not trigger drag\n const target = event.target as HTMLElement;\n if (\n target.closest(INTERACTIVE_ELEMENT_SELECTOR) ||\n findNoDragElement(target, ctx.element) !== null\n ) {\n return;\n }\n\n // Track the finger that pressed this draggable; the others are ignored for the gesture.\n const touch = 'touches' in event ? PointerDragHandler.#pressingTouch(event, ctx.element) : null;\n if ('touches' in event && !touch) {\n return;\n }\n\n const delay = ctx.dragDelay;\n\n // For touch events with a delay configured, DON'T call preventDefault() on touchstart.\n // This allows native scrolling to work if the user swipes before the delay fires.\n // For mouse events or touch without delay, prevent default immediately to avoid\n // text selection and other default behaviors.\n if (!isTouch || delay === 0) {\n event.preventDefault();\n }\n event.stopPropagation();\n\n // A second finger on this draggable while the first is still down: keep following the first.\n if ('touches' in event && touch && this.#isTracking && this.#trackedTouch(event.touches)) {\n return;\n }\n\n // Only one drag at a time: a second finger or a press during a keyboard drag must not\n // replace the drag in progress. The press keeps the default handling above, so a mouse press\n // still doesn't focus this item (which would take the keys of a keyboard drag).\n if (this.#deps.callbacks.isOtherDragActive()) {\n return;\n }\n\n this.#isTracking = true;\n if (touch) {\n this.#touchId = touch.identifier;\n this.#startPosition = { x: touch.clientX, y: touch.clientY };\n } else {\n const mouse = event as MouseEvent;\n this.#startPosition = { x: mouse.clientX, y: mouse.clientY };\n }\n\n // Handle drag delay. A repeated press (e.g. after a release the page never saw) restarts the\n // delay; the previous timer must not survive, or it fires after the gesture has ended.\n this.#cancelDelayTimer();\n if (delay > 0) {\n this.#delayTimerId = setTimeout(() => {\n this.#delayTimerId = null;\n // Another drag started while this press was held: drop the press rather than show it\n // as ready to drag during that drag.\n if (this.#deps.callbacks.isOtherDragActive()) {\n this.cleanup();\n return;\n }\n this.#delayReady = true;\n this.#deps.callbacks.onPendingChange(true); // Emit ready state when delay passes\n }, delay);\n } else {\n this.#delayReady = true;\n }\n\n // Add document-level event listeners\n this.#deps.ngZone.runOutsideAngular(() => {\n if (isTouch) {\n document.addEventListener('touchmove', this.#boundPointerMove!, { passive: false });\n document.addEventListener('touchend', this.#boundPointerUp!);\n document.addEventListener('touchcancel', this.#boundPointerUp!);\n } else {\n document.addEventListener('mousemove', this.#boundPointerMove!);\n document.addEventListener('mouseup', this.#boundPointerUp!);\n }\n // Listen for Escape key on document to cancel drag\n document.addEventListener('keydown', this.#boundKeyDown!);\n // Switching windows or tabs mid-drag means the release never reaches this page: cancel\n // instead of leaving the drag active until the next press.\n window.addEventListener('blur', this.#boundWindowBlur!);\n document.addEventListener('visibilitychange', this.#boundVisibilityChange!);\n });\n }\n\n /**\n * Remove listeners + cancel timers.\n * Called after pointer up or when cancelling.\n */\n cleanup(): void {\n this.#isTracking = false;\n this.#startPosition = null;\n this.#touchId = null;\n this.#deps.callbacks.onPendingChange(false); // Clear pending state on cleanup\n this.#cancelDelayTimer();\n\n // Server rendering destroys the directive without a global document, and never added any\n if (typeof document === 'undefined') {\n return;\n }\n\n // Remove event listeners\n if (this.#boundPointerMove) {\n document.removeEventListener('mousemove', this.#boundPointerMove);\n document.removeEventListener('touchmove', this.#boundPointerMove);\n }\n if (this.#boundPointerUp) {\n document.removeEventListener('mouseup', this.#boundPointerUp);\n document.removeEventListener('touchend', this.#boundPointerUp);\n document.removeEventListener('touchcancel', this.#boundPointerUp);\n }\n if (this.#boundKeyDown) {\n document.removeEventListener('keydown', this.#boundKeyDown);\n }\n if (this.#boundWindowBlur) {\n window.removeEventListener('blur', this.#boundWindowBlur);\n }\n if (this.#boundVisibilityChange) {\n document.removeEventListener('visibilitychange', this.#boundVisibilityChange);\n }\n }\n\n /**\n * Teardown when the directive is destroyed: removes listeners and cancels timers.\n */\n destroy(): void {\n this.cleanup();\n }\n\n /**\n * Handle pointer move (mouse or touch).\n */\n #onPointerMove(event: MouseEvent | TouchEvent): void {\n if (!this.#isTracking) {\n return;\n }\n\n let position: CursorPosition;\n if ('touches' in event) {\n // `touches` holds every finger's current position, so the tracked finger's is there even\n // when only another finger moved\n const touch = this.#trackedTouch(event.touches) ?? this.#trackedTouch(event.changedTouches);\n if (!touch) {\n // The tracked finger is gone. While dragging, keep other fingers from scrolling the page.\n if (this.#deps.callbacks.isDragging()) {\n event.preventDefault();\n }\n return;\n }\n position = { x: touch.clientX, y: touch.clientY };\n } else {\n position = { x: event.clientX, y: event.clientY };\n }\n const ctx = this.#deps.getContext();\n\n // Check if we've moved past the threshold\n if (!this.#deps.callbacks.isDragging() && this.#startPosition) {\n const distance = Math.sqrt(\n Math.pow(position.x - this.#startPosition.x, 2) +\n Math.pow(position.y - this.#startPosition.y, 2),\n );\n\n if (distance < ctx.dragThreshold) {\n return;\n }\n\n // If delay is configured and not yet ready, cancel the drag attempt\n // (user moved before the delay was satisfied).\n // DON'T call preventDefault() here - let native scrolling take over.\n if (!this.#delayReady) {\n this.#cancelDelayTimer();\n this.cleanup();\n return;\n }\n\n // Another press won the race and started its drag first: give up this one.\n if (this.#deps.callbacks.isOtherDragActive()) {\n this.cleanup();\n return;\n }\n\n // Start the drag - now we can prevent default\n event.preventDefault();\n this.#deps.callbacks.onDragStart(position);\n } else if (this.#deps.callbacks.isDragging()) {\n // Already dragging - prevent default to stop scrolling\n event.preventDefault();\n }\n\n // Only update drag if we're actually dragging\n if (!this.#deps.callbacks.isDragging()) {\n return;\n }\n\n // Notify the directive of the new position — it queues this into the scheduler\n // (DragSchedulerService) which coalesces multiple moves per frame into one RAF tick.\n this.#deps.callbacks.onDragMove(position);\n }\n\n /**\n * Handle pointer up (mouse or touch).\n */\n #onPointerUp(event: MouseEvent | TouchEvent): void {\n if (!this.#isTracking) {\n return;\n }\n\n // Another finger lifted (or was cancelled) while the tracked one is still down. Touches\n // without an identifier (malformed synthetic events) can't be told apart: any release ends.\n if (\n 'touches' in event &&\n typeof this.#touchId === 'number' &&\n this.#trackedTouch(event.changedTouches) === null &&\n this.#trackedTouch(event.touches) !== null\n ) {\n return;\n }\n\n // Only prevent default if we were actually dragging\n // Otherwise, allow native touch behavior (like scroll momentum) to complete\n if (this.#deps.callbacks.isDragging()) {\n event.preventDefault();\n // The system took the touch (an incoming call, an OS gesture, too many fingers): the user\n // never released, so this is a cancel, not a drop\n this.#deps.callbacks.onDragEnd(event.type === 'touchcancel');\n }\n\n this.cleanup();\n }\n\n /**\n * Cancel the delay timer if active.\n */\n #cancelDelayTimer(): void {\n if (this.#delayTimerId !== null) {\n clearTimeout(this.#delayTimerId);\n this.#delayTimerId = null;\n }\n this.#delayReady = false;\n }\n\n /**\n * Handle keydown events on document to cancel drag with Escape.\n */\n #onEscapeKeyDown(event: KeyboardEvent): void {\n if (event.key === 'Escape' && this.#deps.callbacks.isDragging()) {\n // No ngZone.run() needed - #endDrag uses signals which work outside zone\n this.#deps.callbacks.onDragEnd(true);\n this.cleanup();\n }\n }\n\n /**\n * Cancel the drag (or drop the pending press) when the window loses focus.\n */\n #onFocusLost(): void {\n if (!this.#isTracking) {\n return;\n }\n\n if (this.#deps.callbacks.isDragging()) {\n this.#deps.callbacks.onDragEnd(true);\n }\n this.cleanup();\n }\n\n /**\n * Treat the page being hidden (tab switch, app switch on mobile) as focus loss.\n */\n #onVisibilityChange(): void {\n if (document.visibilityState === 'hidden') {\n this.#onFocusLost();\n }\n }\n\n /**\n * The tracked finger in `touches`, or null. Synthetic touch events (e.g. from test tools) can\n * leave a list undefined, so a missing list counts as empty.\n */\n #trackedTouch(touches: TouchList | undefined): Touch | null {\n return Array.from(touches ?? []).find((touch) => touch.identifier === this.#touchId) ?? null;\n }\n\n /**\n * The finger that pressed this draggable: of the touches that started with this event, the\n * one on the draggable (several fingers can land in one touchstart).\n */\n static #pressingTouch(event: TouchEvent, element: HTMLElement): Touch | null {\n // Either list can be undefined on synthetic events\n const started = Array.from((event.changedTouches as TouchList | undefined) ?? []);\n const onElement = started.find(\n (touch) => touch.target instanceof Node && element.contains(touch.target),\n );\n return onElement ?? started[0] ?? Array.from(event.touches ?? [])[0] ?? null;\n }\n}\n","import {\n computed,\n Directive,\n ElementRef,\n EnvironmentInjector,\n inject,\n input,\n NgZone,\n OnDestroy,\n OnInit,\n output,\n signal,\n} from '@angular/core';\nimport { DragStateService } from '../services/drag-state.service';\nimport { PositionCalculatorService } from '../services/position-calculator.service';\nimport { AutoScrollService } from '../services/auto-scroll.service';\nimport { ElementCloneService } from '../services/element-clone.service';\nimport { KeyboardDragService } from '../services/keyboard-drag.service';\nimport { DragIndexCalculatorService } from '../services/drag-index-calculator.service';\nimport { OverlayContainerService } from '../services/overlay-container.service';\nimport { DragSchedulerService } from '../services/drag-scheduler.service';\nimport {\n CursorPosition,\n DragEndEvent,\n DragStartEvent,\n GrabOffset,\n} from '../models/drag-drop.models';\nimport { VDND_GROUP_TOKEN } from './droppable-group.directive';\nimport { createEffectiveGroupSignal } from '../utils/group-resolution';\nimport { KeyboardDragHandler } from '../handlers/keyboard-drag.handler';\nimport { PointerDragHandler } from '../handlers/pointer-drag.handler';\nimport { normalizeDropDestinationIndex } from '../utils/drop-index-normalization';\nimport { findNoDragElement, INTERACTIVE_ELEMENT_SELECTOR } from '../utils/interactive-elements';\n\n/**\n * Makes an element draggable within the virtual scroll drag-and-drop system.\n *\n * @example\n * ```html\n * <!-- With explicit group -->\n * <div\n * vdndDraggable=\"item-1\"\n * vdndDraggableGroup=\"my-group\"\n * [vdndDraggableData]=\"item\">\n * Drag me!\n * </div>\n *\n * <!-- With inherited group from parent vdndGroup directive -->\n * <div vdndGroup=\"my-group\">\n * <div vdndDraggable=\"item-1\" [vdndDraggableData]=\"item\">\n * Drag me!\n * </div>\n * </div>\n * ```\n */\n@Directive({\n selector: '[vdndDraggable]',\n host: {\n '[attr.data-draggable-id]': 'vdndDraggable()',\n '[class.vdnd-draggable]': 'true',\n '[class.vdnd-draggable-dragging]': 'isDragging()',\n '[class.vdnd-draggable-disabled]': 'disabled()',\n '[class.vdnd-drag-pending]': 'isPending()',\n '[style.display]': 'isDragging() ? \"none\" : null',\n '[attr.aria-grabbed]': 'isDragging() ? \"true\" : \"false\"',\n '[tabindex]': 'disabled() ? -1 : 0',\n '(mousedown)': 'onPointerDown($event, false)',\n '(touchstart)': 'onPointerDown($event, true)',\n '(keydown.space)': 'onKeyboardActivate($event)',\n '(keydown.enter)': 'onEnterKey($event)',\n '(keydown.arrowup)': 'onArrowKey($event)',\n '(keydown.arrowdown)': 'onArrowKey($event)',\n '(keydown.arrowleft)': 'onArrowKey($event)',\n '(keydown.arrowright)': 'onArrowKey($event)',\n '(keydown.escape)': 'onEscape()',\n },\n})\nexport class DraggableDirective implements OnInit, OnDestroy {\n readonly #elementRef = inject(ElementRef<HTMLElement>);\n readonly #dragState = inject(DragStateService);\n readonly #positionCalculator = inject(PositionCalculatorService);\n readonly #autoScroll = inject(AutoScrollService);\n readonly #elementClone = inject(ElementCloneService);\n readonly #keyboardDrag = inject(KeyboardDragService);\n readonly #dragIndexCalculator = inject(DragIndexCalculatorService);\n readonly #overlayContainer = inject(OverlayContainerService);\n readonly #scheduler = inject(DragSchedulerService);\n readonly #ngZone = inject(NgZone);\n readonly #envInjector = inject(EnvironmentInjector);\n readonly #parentGroup = inject(VDND_GROUP_TOKEN, { optional: true });\n\n /** Unique identifier for this draggable */\n vdndDraggable = input.required<string>();\n\n /**\n * Drag-and-drop group name.\n * Optional when a parent `vdndGroup` directive provides the group context.\n */\n vdndDraggableGroup = input<string>();\n\n /**\n * Resolved group name - uses explicit input or falls back to parent group.\n * Returns null (and disables drag) if neither is available.\n */\n readonly #effectiveGroup = createEffectiveGroupSignal({\n explicitGroup: this.vdndDraggableGroup,\n parentGroup: this.#parentGroup,\n elementId: this.vdndDraggable,\n elementType: 'draggable',\n });\n\n /** Optional data associated with this draggable */\n vdndDraggableData = input<unknown>();\n\n /** Whether this draggable is disabled */\n disabled = input<boolean>(false);\n\n /** CSS selector for drag handle (if not provided, entire element is draggable) */\n dragHandle = input<string>();\n\n /** Minimum distance to move before drag starts (prevents accidental drags) */\n dragThreshold = input<number>(5);\n\n /**\n * Delay in milliseconds before drag starts after pointer down.\n * User must hold without moving for this duration.\n * Set to 0 for immediate drag (default behavior).\n */\n dragDelay = input<number>(0);\n\n /**\n * Lock dragging by freezing one axis. The value names the axis that stays\n * fixed: `'x'` freezes the X coordinate (vertical-only movement), `'y'`\n * freezes the Y coordinate (horizontal-only movement). `null` allows free\n * movement. Note: this is the opposite of Angular CDK's `cdkDragLockAxis`.\n */\n lockAxis = input<'x' | 'y' | null>(null);\n\n /** Emits when drag starts */\n dragStart = output<DragStartEvent>();\n\n /** Emits when drag ends */\n dragEnd = output<DragEndEvent>();\n\n /** Whether this element is in the \"ready to drag\" state (delay has passed) */\n #isPending = signal(false);\n readonly isPending = this.#isPending.asReadonly();\n\n /** Whether this element is currently being dragged (based on global drag state) */\n readonly isDragging = computed(() => {\n const draggedItem = this.#dragState.draggedItem();\n return draggedItem?.draggableId === this.vdndDraggable();\n });\n\n #keyboardHandler!: KeyboardDragHandler;\n #pointerHandler!: PointerDragHandler;\n\n /** Set by ngOnInit, which creates the handlers */\n #initialized = false;\n\n /** Cached constraint flag from source droppable */\n #constrainToContainer = false;\n\n /** Element whose rect is used for clamping (scroll container or droppable itself) */\n #constraintElement: HTMLElement | null = null;\n\n /** Last raw pointer position from pointer move events (not clamped) */\n #lastRawPosition: CursorPosition | null = null;\n\n /**\n * Update the pending state and emit the change event.\n */\n #setPending(pending: boolean): void {\n if (this.#isPending() !== pending) {\n this.#isPending.set(pending);\n }\n }\n\n /**\n * Find the element to use for container constraint clamping.\n * If the droppable is inside a scrollable container, use that container's rect\n * (which represents the visible viewport) instead of the droppable's rect\n * (which may extend far beyond the viewport in virtual scroll scenarios).\n */\n #findConstraintElement(droppableElement: HTMLElement | null): HTMLElement | null {\n if (!droppableElement) return null;\n const scrollable = droppableElement.closest('.vdnd-scrollable');\n return (scrollable as HTMLElement) ?? droppableElement;\n }\n\n ngOnInit(): void {\n this.#keyboardHandler = new KeyboardDragHandler({\n dragState: this.#dragState,\n keyboardDrag: this.#keyboardDrag,\n positionCalculator: this.#positionCalculator,\n dragIndexCalculator: this.#dragIndexCalculator,\n elementClone: this.#elementClone,\n overlayContainer: this.#overlayContainer,\n ngZone: this.#ngZone,\n envInjector: this.#envInjector,\n callbacks: {\n onDragStart: (event) => this.dragStart.emit(event),\n onDragEnd: (event) => this.dragEnd.emit(event),\n getParentDroppableId: () => this.#getParentDroppableId(),\n calculateSourceIndex: (el, droppable) => this.#calculateSourceIndex(el, droppable),\n },\n getContext: () => ({\n element: this.#elementRef.nativeElement,\n draggableId: this.vdndDraggable(),\n groupName: this.#effectiveGroup(),\n data: this.vdndDraggableData(),\n }),\n });\n\n this.#pointerHandler = new PointerDragHandler({\n ngZone: this.#ngZone,\n callbacks: {\n onDragStart: (position) => this.#startDrag(position),\n onDragMove: (position) => {\n // Record raw position synchronously (needed for autoscroll cursor override)\n // then queue into the scheduler's RAF loop for coalesced frame-rate processing.\n this.#lastRawPosition = position;\n this.#scheduler.queueCursorUpdate(position);\n },\n onDragEnd: (cancelled) => this.#endDrag(cancelled),\n onPendingChange: (pending) => this.#setPending(pending),\n isDragging: () => this.isDragging(),\n isOtherDragActive: () => this.#dragState.isDragging() && !this.isDragging(),\n },\n getContext: () => ({\n element: this.#elementRef.nativeElement,\n groupName: this.#effectiveGroup(),\n disabled: this.disabled(),\n dragHandle: this.dragHandle(),\n dragThreshold: this.dragThreshold(),\n dragDelay: this.dragDelay(),\n }),\n });\n\n this.#initialized = true;\n }\n\n ngOnDestroy(): void {\n // Destroyed before its first change detection: there are no handlers yet, and its inputs\n // have no values (reading a bound ID would throw).\n if (!this.#initialized) {\n return;\n }\n\n // If destroyed mid-drag, cancel to avoid stale global state / ongoing RAF loops.\n if (this.isDragging()) {\n this.#endDrag(true);\n }\n this.#pointerHandler.destroy();\n this.#keyboardHandler.destroy();\n }\n\n /**\n * Handle pointer down (mouse or touch).\n */\n protected onPointerDown(event: MouseEvent | TouchEvent, isTouch: boolean): void {\n this.#pointerHandler.onPointerDown(event, isTouch);\n }\n\n /**\n * Handle keyboard activation (space key).\n * Starts a keyboard drag if not dragging, or drops if already in keyboard drag mode.\n */\n protected onKeyboardActivate(event: Event): void {\n if (this.disabled()) {\n return;\n }\n\n // Space on a control inside the item types into it or clicks it, just as a press on\n // one never starts a pointer drag.\n if (this.#isFromNestedControl(event)) {\n return;\n }\n\n event.preventDefault();\n\n // If we're in a keyboard drag, Space drops the item\n if (this.#keyboardHandler.isActive()) {\n event.stopPropagation(); // Prevent document listener from receiving this event\n this.#keyboardHandler.complete();\n return;\n }\n\n // Another drag is in progress: don't replace it. The key goes on to the document, where a\n // keyboard drag of another item drops with it.\n if (this.#dragState.isDragging()) {\n return;\n }\n\n // Start keyboard drag. The document listener it adds must not receive this event.\n event.stopPropagation();\n this.#keyboardHandler.activate();\n }\n\n /**\n * Whether the event comes from a control (or from inside a `no-drag` element) nested inside this\n * draggable. Neither the draggable itself nor a control around it counts, so a\n * `<button vdndDraggable>` still picks up with Space, and neither does a control that is the\n * drag handle, such as a button handle. Controls inside the handle do count.\n */\n #isFromNestedControl(event: Event): boolean {\n const host = this.#elementRef.nativeElement;\n const target = event.target;\n if (!(target instanceof Element) || target === host) {\n return false;\n }\n\n if (findNoDragElement(target, host) !== null) {\n return true;\n }\n\n const control = target.closest(INTERACTIVE_ELEMENT_SELECTOR);\n if (control === null || control === host || !host.contains(control)) {\n return false;\n }\n\n const handleSelector = this.dragHandle();\n return !handleSelector || !control.matches(handleSelector);\n }\n\n /**\n * Handle Enter key (alternative to Space for dropping during keyboard drag).\n */\n protected onEnterKey(event: Event): void {\n if (this.#keyboardHandler.isActive()) {\n event.preventDefault();\n this.#keyboardHandler.complete();\n }\n }\n\n /**\n * Handle arrow keys during keyboard drag.\n */\n protected onArrowKey(event: Event): void {\n if (this.#keyboardHandler.isActive()) {\n this.#keyboardHandler.handleKey(event as KeyboardEvent);\n }\n }\n\n /**\n * Handle escape key to cancel drag (host binding, fires before element is hidden).\n */\n protected onEscape(): boolean {\n if (this.#keyboardHandler.isActive()) {\n this.#keyboardHandler.cancel();\n return false;\n }\n if (this.isDragging()) {\n this.#endDrag(true);\n this.#pointerHandler.cleanup();\n return false; // Prevents default\n }\n return true;\n }\n\n /**\n * Start the drag operation.\n */\n #startDrag(position: CursorPosition): void {\n // Clear pending state - drag is now active\n this.#setPending(false);\n\n const element = this.#elementRef.nativeElement;\n const rect = element.getBoundingClientRect();\n\n // Calculate grab offset using the START position (where user initially pressed down)\n // NOT the current position (where drag threshold was exceeded)\n // This ensures the preview maintains its position relative to where the user grabbed it\n const startPos = this.#pointerHandler.getStartPosition() ?? position;\n const grabOffset: GrabOffset = {\n x: startPos.x - rect.left,\n y: startPos.y - rect.top,\n };\n\n // Clone element BEFORE updating drag state (which triggers display:none via host binding).\n // Template-first: skip the costly getComputedStyle deep-walk when a template-based\n // preview is mounted, since that clone would never be rendered.\n const clonedElement = this.#overlayContainer.hasTemplatePreview()\n ? undefined\n : this.#elementClone.cloneElement(element);\n\n // Find droppable and calculate initial placeholder position\n // This fixes the UI glitch by ensuring placeholder is set before the element is hidden\n const groupName = this.#effectiveGroup();\n if (!groupName) {\n // Misconfigured - cancel tracking and don't start drag.\n this.#pointerHandler.cleanup();\n return;\n }\n\n const parentDroppableElement = this.#positionCalculator.getDroppableParent(element, groupName);\n const parentDroppableId = parentDroppableElement\n ? this.#positionCalculator.getDroppableId(parentDroppableElement)\n : null;\n\n // Snapshot droppable rects for this drag session so subsequent hit-testing is\n // pure geometry (no elementFromPoint layout flush per pointermove).\n this.#positionCalculator.beginDragSession(groupName);\n\n const droppableElement = this.#positionCalculator.findDroppableAtPoint(\n position.x,\n position.y,\n element,\n groupName,\n );\n\n // Cache constraint flag and element for clamping during drag\n this.#constrainToContainer =\n droppableElement?.hasAttribute('data-constrain-to-container') ?? false;\n this.#constraintElement = this.#constrainToContainer\n ? this.#findConstraintElement(droppableElement)\n : null;\n\n const activeDroppableId = droppableElement\n ? this.#positionCalculator.getDroppableId(droppableElement)\n : parentDroppableId;\n\n // Calculate source index BEFORE the element is hidden (display: none)\n // This is critical because getBoundingClientRect() returns all zeros for hidden elements\n const sourceIndex = this.#calculateSourceIndex(element, parentDroppableElement);\n\n let initialPlaceholderId: string | null = null;\n let initialPlaceholderIndex: number | null = null;\n\n if (droppableElement) {\n const indexResult = this.#dragIndexCalculator.calculatePlaceholderIndex({\n droppableElement,\n position,\n previousPosition: null,\n grabOffset,\n draggedItemHeight: rect.height,\n sourceDroppableId: parentDroppableId,\n sourceIndex,\n });\n initialPlaceholderIndex = indexResult.index;\n initialPlaceholderId = indexResult.placeholderId;\n }\n\n const lockAxis = this.lockAxis();\n\n // Register with drag state service - this triggers isDragging computed to become true\n // which will apply display:none via host binding\n // No ngZone.run() needed - signals work outside zone and effects react automatically\n this.#dragState.startDrag(\n {\n draggableId: this.vdndDraggable(),\n droppableId: parentDroppableId ?? '',\n element,\n clonedElement,\n height: rect.height,\n width: rect.width,\n data: this.vdndDraggableData(),\n },\n position,\n grabOffset,\n lockAxis,\n activeDroppableId,\n initialPlaceholderId,\n initialPlaceholderIndex,\n sourceIndex,\n undefined,\n lockAxis ? startPos : undefined,\n );\n\n // Start the scheduler RAF loop (drives pointer-move updates + autoscroll participant).\n // onTick is called each frame: when cursor is dirty, run full #updateDrag.\n this.#scheduler.start((cursor, cursorDirty) => {\n if (cursorDirty && cursor && this.isDragging()) {\n this.#updateDrag(cursor);\n }\n });\n\n // Start auto-scroll monitoring — registers as a scheduler participant.\n this.#autoScroll.startMonitoring(() => this.#recalculatePlaceholder());\n\n // Emit drag start event\n this.dragStart.emit({\n draggableId: this.vdndDraggable(),\n droppableId: parentDroppableId ?? '',\n data: this.vdndDraggableData(),\n position,\n sourceIndex,\n });\n }\n\n /**\n * Calculate the source index of the dragged element BEFORE it's hidden.\n * This must be called before startDrag updates the state (which triggers display:none).\n * Uses strategy-based lookup when available for accurate handling of variable heights.\n */\n #calculateSourceIndex(element: HTMLElement, droppableElement: HTMLElement | null): number {\n if (!droppableElement) {\n return 0;\n }\n\n const rect = element.getBoundingClientRect();\n // The same measurement that places the placeholder: it knows each container's scroll\n // element and subtracts space reserved above the rows (contentOffset, page headers).\n const geometry = this.#dragIndexCalculator.getScrollGeometry(droppableElement, rect.height);\n const relativeY = rect.top - geometry.rect.top + geometry.scrollTop;\n\n // Try to use registered strategy for accurate offset-based lookup\n const droppableId = this.#positionCalculator.getDroppableId(droppableElement);\n if (droppableId) {\n const strategy = this.#dragIndexCalculator.getStrategyForDroppable(droppableId);\n if (strategy) {\n return strategy.findIndexAtOffset(relativeY);\n }\n }\n\n // Preserve the geometry fallback for a virtual container whose strategy is unavailable.\n if (geometry.isVirtual) {\n const itemHeight = rect.height || 50;\n return Math.round(relativeY / itemHeight);\n }\n\n // Non-virtual fallback: derive the logical index from preceding draggable siblings.\n // Geometry-based division is incorrect when the list has padding, gaps, margins,\n // or variable-height items.\n let sourceIndex = 0;\n let sibling = element.previousElementSibling;\n while (sibling) {\n if (sibling.matches('[data-draggable-id]')) {\n sourceIndex++;\n }\n sibling = sibling.previousElementSibling;\n }\n return sourceIndex;\n }\n\n /**\n * Recalculate placeholder position (called during auto-scroll).\n *\n * Scroll-only fast path: the cursor has not moved — only `scrollTop` changed.\n * When the active droppable is already known, skip hit-testing entirely and\n * recalculate only the placeholder index within that droppable. This avoids the\n * `findDroppableAtPoint` geometry scan + the `invalidateDroppableRects` DOM round-trip\n * on every autoscroll frame while still recomputing the correct insertion index.\n *\n * Falls back to the full `#updateDrag` pipeline when no droppable is active (e.g.\n * cursor drifted outside all droppables before the scroll tick fired).\n */\n #recalculatePlaceholder(): void {\n const cursorPosition = this.#dragState.cursorPosition();\n if (!cursorPosition || !this.isDragging()) {\n return;\n }\n\n const activeDroppableId = this.#dragState.activeDroppableId();\n if (activeDroppableId) {\n const droppableElement = this.#positionCalculator.getDroppableById(activeDroppableId);\n if (droppableElement) {\n const draggedItemHeight = this.#dragState.draggedItem()?.height ?? 50;\n const indexResult = this.#dragIndexCalculator.calculatePlaceholderIndex({\n droppableElement,\n position: cursorPosition,\n previousPosition: cursorPosition,\n grabOffset: this.#dragState.grabOffset(),\n draggedItemHeight,\n sourceDroppableId: this.#dragState.sourceDroppableId(),\n sourceIndex: this.#dragState.sourceIndex(),\n });\n this.#dragState.updateScrollOnlyPlaceholder(indexResult.placeholderId, indexResult.index);\n return;\n }\n }\n\n // Fallback: full recalculation when no active droppable is known.\n // Mark rects dirty first since autoscroll moved the container before the scroll event fires.\n this.#positionCalculator.invalidateDroppableRects();\n this.#updateDrag(cursorPosition);\n }\n\n /**\n * Clamp cursor position to source container boundaries when constrainToContainer is enabled.\n */\n #clampToContainer(position: CursorPosition): CursorPosition {\n if (!this.#constrainToContainer || !this.#constraintElement) {\n return position;\n }\n\n const containerRect = this.#constraintElement.getBoundingClientRect();\n const grabOffset = this.#dragState.grabOffset();\n if (!grabOffset) {\n return position;\n }\n\n const draggedItem = this.#dragState.draggedItem();\n const itemHeight = draggedItem?.height ?? 0;\n const itemWidth = draggedItem?.width ?? 0;\n\n const minY = containerRect.top + grabOffset.y + 1;\n const maxY = containerRect.bottom - (itemHeight - grabOffset.y) - 1;\n const minX = containerRect.left + grabOffset.x + 1;\n const maxX = containerRect.right - (itemWidth - grabOffset.x) - 1;\n\n return {\n x: Math.max(minX, Math.min(position.x, maxX)),\n y: Math.max(minY, Math.min(position.y, maxY)),\n };\n }\n\n /**\n * Update the drag position.\n * @param position Current cursor position\n */\n #updateDrag(position: CursorPosition): void {\n const element = this.#elementRef.nativeElement;\n const groupName = this.#effectiveGroup();\n if (!groupName) {\n // Group became unavailable mid-drag; cancel to avoid inconsistent state.\n this.#endDrag(true);\n this.#pointerHandler.cleanup();\n return;\n }\n\n // Apply axis locking to effective position for droppable detection\n // When axis is locked, use the start position for the locked axis\n const axisLock = this.lockAxis();\n const startPos = this.#pointerHandler.getStartPosition();\n let effectivePosition = position;\n\n if (axisLock && startPos) {\n effectivePosition = {\n x: axisLock === 'x' ? startPos.x : position.x,\n y: axisLock === 'y' ? startPos.y : position.y,\n };\n }\n\n // Apply container clamping after axis locking\n effectivePosition = this.#clampToContainer(effectivePosition);\n\n // Update autoscroll cursor: use raw pointer position clamped to container\n // edges (without grabOffset) so autoscroll threshold is reachable regardless\n // of where the user grabbed the item.\n if (this.#constrainToContainer && this.#constraintElement && this.#lastRawPosition) {\n const rect = this.#constraintElement.getBoundingClientRect();\n let scrollCursor: CursorPosition = this.#lastRawPosition;\n if (axisLock && startPos) {\n scrollCursor = {\n x: axisLock === 'x' ? startPos.x : scrollCursor.x,\n y: axisLock === 'y' ? startPos.y : scrollCursor.y,\n };\n }\n this.#autoScroll.setCursorOverride({\n x: Math.max(rect.left, Math.min(scrollCursor.x, rect.right)),\n y: Math.max(rect.top, Math.min(scrollCursor.y, rect.bottom)),\n });\n }\n\n // Find droppable at effective position (respects axis locking and clamping)\n const droppableElement = this.#positionCalculator.findDroppableAtPoint(\n effectivePosition.x,\n effectivePosition.y,\n element,\n groupName,\n );\n\n const activeDroppableId = droppableElement\n ? this.#positionCalculator.getDroppableId(droppableElement)\n : null;\n\n let placeholderId: string | null = null;\n let placeholderIndex: number | null = null;\n\n if (droppableElement) {\n // Calculate placeholder index based on effective position using mathematical approach\n // This is more stable than DOM-based detection because it doesn't get affected\n // by the placeholder insertion shifting elements around\n const draggedItemHeight = this.#dragState.draggedItem()?.height ?? 50;\n const indexResult = this.#dragIndexCalculator.calculatePlaceholderIndex({\n droppableElement,\n position: effectivePosition,\n previousPosition: this.#dragState.cursorPosition(),\n grabOffset: this.#dragState.grabOffset(),\n draggedItemHeight,\n sourceDroppableId: this.#dragState.sourceDroppableId(),\n sourceIndex: this.#dragState.sourceIndex(),\n });\n placeholderIndex = indexResult.index;\n placeholderId = indexResult.placeholderId;\n }\n\n // Update drag state with effective position (respects axis locking and container clamping)\n // No ngZone.run() needed - signals work outside zone and effects react automatically\n this.#dragState.updateDragPosition({\n cursorPosition: effectivePosition,\n activeDroppableId,\n placeholderId,\n placeholderIndex,\n });\n }\n\n /**\n * End the drag operation.\n */\n #endDrag(cancelled: boolean): void {\n // Flush the final pointer position for a real drop. Pointer moves only QUEUE a cursor\n // for the next RAF tick; on release the scheduler is stopped below and any un-processed\n // cursor is discarded, so without this the drop would resolve against the last\n // RAF-PROCESSED position — a release that just entered a different (e.g. newly disabled)\n // droppable could otherwise land on the previously-targeted one. Guarded on group\n // presence so it never re-enters #endDrag via #updateDrag's group-lost cancel path.\n // Cancels skip this: their destination is intentionally null.\n if (!cancelled && this.#lastRawPosition && this.isDragging() && this.#effectiveGroup()) {\n this.#updateDrag(this.#lastRawPosition);\n }\n\n // Stop the scheduler RAF loop first, then remove the autoscroll participant.\n this.#scheduler.stop();\n this.#autoScroll.stopMonitoring();\n\n // Tear down the geometric hit-testing snapshot + its viewport listeners\n this.#positionCalculator.endDragSession();\n\n // Clear droppable metadata cache from this drag session\n this.#dragIndexCalculator.clearCache();\n\n // Reset cached constraint state\n this.#constrainToContainer = false;\n this.#constraintElement = null;\n this.#lastRawPosition = null;\n\n const sourceIndex = this.#dragState.sourceIndex() ?? 0;\n const destinationIndex = cancelled\n ? null\n : normalizeDropDestinationIndex({\n sourceIndex,\n placeholderIndex: this.#dragState.placeholderIndex(),\n sourceDroppableId: this.#dragState.sourceDroppableId(),\n activeDroppableId: this.#dragState.activeDroppableId(),\n });\n\n // Emit drag end event\n this.dragEnd.emit({\n draggableId: this.vdndDraggable(),\n droppableId: this.#getParentDroppableId() ?? '',\n cancelled,\n data: this.vdndDraggableData(),\n sourceIndex,\n destinationIndex,\n });\n\n // Clear drag state - this triggers isDragging computed to become false\n if (cancelled) {\n this.#dragState.cancelDrag();\n } else {\n this.#dragState.endDrag();\n }\n }\n\n /**\n * Get the parent droppable ID.\n */\n #getParentDroppableId(): string | null {\n const groupName = this.#effectiveGroup();\n if (!groupName) {\n return null;\n }\n\n const droppable = this.#positionCalculator.getDroppableParent(\n this.#elementRef.nativeElement,\n groupName,\n );\n\n return droppable ? this.#positionCalculator.getDroppableId(droppable) : null;\n }\n}\n","import {\n Directive,\n ElementRef,\n inject,\n input,\n NgZone,\n OnDestroy,\n OnInit,\n signal,\n} from '@angular/core';\nimport { VDND_SCROLL_CONTAINER, VdndScrollContainer } from '../tokens/scroll-container.token';\nimport { AutoScrollConfig, AutoScrollService } from '../services/auto-scroll.service';\nimport {\n bindRafThrottledScrollTopSignal,\n bindResizeObserverHeightSignal,\n} from '../utils/dom-signal-bindings';\nimport { createAutoScrollRegistration } from '../utils/auto-scroll-registration';\n\n/**\n * Directive that marks an element as a scrollable container for virtual scrolling.\n *\n * Apply this directive to any scrollable element (with `overflow: auto` or `overflow: scroll`)\n * that contains a `*vdndVirtualFor` directive. The virtual scroll will use this element\n * as its scroll container.\n *\n * @example\n * Basic usage with a custom scroll container:\n * ```html\n * <div vdndScrollable style=\"overflow: auto; height: 400px;\">\n * <ng-container *vdndVirtualFor=\"let item of items(); itemHeight: 50; trackBy: trackById\">\n * <div>{{ item.name }}</div>\n * </ng-container>\n * </div>\n * ```\n *\n * @example\n * With Ionic ion-content:\n * ```html\n * <ion-content vdndScrollable class=\"ion-content-scroll-host\">\n * <ng-container *vdndVirtualFor=\"let item of items(); itemHeight: 50; trackBy: trackById\">\n * <div>{{ item.name }}</div>\n * </ng-container>\n * </ion-content>\n * ```\n *\n * @example\n * With auto-scroll configuration:\n * ```html\n * <div vdndScrollable\n * [autoScrollEnabled]=\"true\"\n * [autoScrollConfig]=\"{ threshold: 80, maxSpeed: 20 }\"\n * style=\"overflow: auto; height: 400px;\">\n * ...\n * </div>\n * ```\n */\n@Directive({\n selector: '[vdndScrollable]',\n providers: [{ provide: VDND_SCROLL_CONTAINER, useExisting: ScrollableDirective }],\n host: {\n class: 'vdnd-scrollable',\n '[style.overflow-anchor]': '\"none\"',\n },\n})\nexport class ScrollableDirective implements VdndScrollContainer, OnInit, OnDestroy {\n readonly #elementRef = inject(ElementRef<HTMLElement>);\n readonly #ngZone = inject(NgZone);\n readonly #autoScrollService = inject(AutoScrollService);\n\n /** Current scroll position (reactive) */\n readonly #scrollTop = signal(0);\n\n /** Measured container height (reactive) */\n readonly #containerHeight = signal(0);\n\n /** Cleanup function for scroll listener */\n #scrollCleanup: (() => void) | null = null;\n #resizeCleanup: (() => void) | null = null;\n\n /** Generated ID for auto-scroll registration */\n #generatedScrollId = `vdnd-scroll-${Math.random().toString(36).slice(2, 9)}`;\n\n // ========== Inputs ==========\n\n /** Unique ID for this scroll container (used for auto-scroll registration) */\n scrollContainerId = input<string>();\n\n /** Whether auto-scroll is enabled when dragging near edges */\n autoScrollEnabled = input<boolean>(true);\n\n /** Auto-scroll configuration */\n autoScrollConfig = input<Partial<AutoScrollConfig>>({});\n\n // ========== VdndScrollContainer Implementation ==========\n\n constructor() {\n createAutoScrollRegistration({\n autoScrollService: this.#autoScrollService,\n getElement: () => this.nativeElement,\n getId: () => this.scrollContainerId() ?? this.#generatedScrollId,\n enabled: () => this.autoScrollEnabled(),\n config: () => this.autoScrollConfig(),\n });\n }\n\n get nativeElement(): HTMLElement {\n return this.#elementRef.nativeElement;\n }\n\n scrollTop(): number {\n return this.#scrollTop();\n }\n\n scrollTo(options: ScrollToOptions): void {\n this.nativeElement.scrollTo(options);\n }\n\n // ========== Additional API ==========\n\n /** Get the measured container height */\n containerHeight(): number {\n return this.#containerHeight();\n }\n\n /** Scroll by a delta amount */\n scrollBy(delta: number): void {\n const newPosition = Math.max(\n 0,\n Math.min(\n this.scrollTop() + delta,\n this.nativeElement.scrollHeight - this.nativeElement.clientHeight,\n ),\n );\n this.scrollTo({ top: newPosition });\n }\n\n // ========== Lifecycle ==========\n\n ngOnInit(): void {\n this.#setupScrollListener();\n this.#setupResizeObserver();\n }\n\n ngOnDestroy(): void {\n this.#scrollCleanup?.();\n this.#resizeCleanup?.();\n }\n\n // ========== Private Methods ==========\n\n /** Minimum scroll delta (px) to trigger signal update */\n readonly #scrollThreshold = 5;\n\n #setupScrollListener(): void {\n this.#scrollCleanup = bindRafThrottledScrollTopSignal({\n element: this.nativeElement,\n ngZone: this.#ngZone,\n scrollTop: this.#scrollTop,\n thresholdPx: this.#scrollThreshold,\n });\n }\n\n #setupResizeObserver(): void {\n this.#resizeCleanup = bindResizeObserverHeightSignal({\n element: this.nativeElement,\n ngZone: this.#ngZone,\n height: this.#containerHeight,\n minDeltaPx: 1,\n });\n }\n}\n","import {\n computed,\n Directive,\n effect,\n ElementRef,\n EmbeddedViewRef,\n inject,\n Injector,\n input,\n isDevMode,\n NgZone,\n OnDestroy,\n OnInit,\n PLATFORM_ID,\n TemplateRef,\n untracked,\n ViewContainerRef,\n} from '@angular/core';\nimport { isPlatformBrowser } from '@angular/common';\nimport { VDND_SCROLL_CONTAINER } from '../tokens/scroll-container.token';\nimport { VDND_OFFSET_ROWS_VIEWPORT, VDND_VIRTUAL_VIEWPORT } from '../tokens/virtual-viewport.token';\nimport { DragStateService } from '../services/drag-state.service';\nimport { DragIndexCalculatorService } from '../services/drag-index-calculator.service';\nimport { DroppableDirective } from './droppable.directive';\nimport type { VirtualScrollStrategy } from '../models/virtual-scroll-strategy';\nimport { FixedHeightStrategy } from '../strategies/fixed-height.strategy';\nimport { DynamicHeightStrategy } from '../strategies/dynamic-height.strategy';\nimport { VDND_ANIMATION_CONFIG } from '../tokens/animation-config.token';\nimport { ShiftAnimationEntry, ShiftAnimator } from '../utils/shift-animator';\n\n/**\n * Context provided to the template for each virtual item.\n */\nexport interface VirtualForContext<T> {\n /** The item data (also available as implicit context) */\n $implicit: T;\n /** The item's index in the original array */\n index: number;\n /** Whether this is the first visible item */\n first: boolean;\n /** Whether this is the last visible item */\n last: boolean;\n /** Count of total items */\n count: number;\n}\n\n/** Render-queue key of the placeholder entry */\nconst PLACEHOLDER_KEY = '__placeholder__';\n\n/**\n * Represents an item entry in the render queue for virtual scrolling.\n * @internal\n */\ninterface RenderEntry<T> {\n type: 'item' | 'placeholder';\n key: unknown;\n context: VirtualForContext<T> | null;\n visualIndex: number;\n}\n\n/**\n * A structural directive for virtual scrolling within custom scroll containers.\n * Provides maximum flexibility for advanced use cases where the component wrapper\n * is not suitable.\n *\n * The directive must be placed inside a container marked with the `vdndScrollable`\n * directive, which provides the scroll container context via dependency injection.\n *\n * Placeholders are handled automatically by the parent component (vdnd-virtual-scroll\n * or vdnd-virtual-content) - consumers just render their items normally.\n *\n * @example\n * Inside a viewport component (itemHeight and droppableId inherited automatically):\n * ```html\n * <vdnd-virtual-viewport [itemHeight]=\"50\" style=\"height: 400px\">\n * <ng-container *vdndVirtualFor=\"let item of items(); trackBy: trackById\">\n * <div class=\"item\">{{ item.name }}</div>\n * </ng-container>\n * </vdnd-virtual-viewport>\n * ```\n *\n * @example\n * Standalone usage (itemHeight required):\n * ```html\n * <div vdndScrollable style=\"overflow: auto; height: 400px\">\n * <ng-container *vdndVirtualFor=\"let item of items(); itemHeight: 50; trackBy: trackById\">\n * <div class=\"item\">{{ item.name }}</div>\n * </ng-container>\n * </div>\n * ```\n */\n@Directive({\n selector: '[vdndVirtualFor][vdndVirtualForOf]',\n})\nexport class VirtualForDirective<T> implements OnInit, OnDestroy {\n readonly #templateRef = inject(TemplateRef<VirtualForContext<T>>);\n readonly #viewContainer = inject(ViewContainerRef);\n readonly #elementRef = inject(ElementRef<Comment>);\n readonly #scrollContainer = inject(VDND_SCROLL_CONTAINER);\n readonly #injector = inject(Injector);\n readonly #ngZone = inject(NgZone);\n readonly #isBrowser = isPlatformBrowser(inject(PLATFORM_ID));\n readonly #dragState = inject(DragStateService);\n readonly #dragIndexCalculator = inject(DragIndexCalculatorService);\n\n /**\n * Optional viewport component that provides wrapper-based positioning.\n * When inside a viewport, items are positioned via the wrapper's transform,\n * so we skip individual absolute positioning.\n */\n readonly #viewport = inject(VDND_VIRTUAL_VIEWPORT, { optional: true });\n\n /** A vdnd-virtual-viewport, whose rows start contentOffset px down (see #rowsScrollTop) */\n readonly #offsetRowsViewport = inject(VDND_OFFSET_ROWS_VIEWPORT, { optional: true });\n\n /**\n * Optional parent droppable directive.\n * When present, droppableId is inherited automatically.\n */\n readonly #droppable = inject(DroppableDirective, { optional: true });\n\n /** Slides items displaced by the placeholder (only when VDND_ANIMATION_CONFIG is provided) */\n readonly #shiftAnimator = this.#createShiftAnimator();\n\n /** Whether we're inside a viewport component (use wrapper positioning) */\n readonly #useViewportPositioning = this.#viewport !== null;\n\n /** Pool of views for reuse */\n readonly #viewPool: EmbeddedViewRef<VirtualForContext<T>>[] = [];\n\n /** Currently active views keyed by their track-by value */\n readonly #activeViews = new Map<unknown, EmbeddedViewRef<VirtualForContext<T>>>();\n\n /** Single spacer element for scroll height */\n #spacer: HTMLDivElement | null = null;\n\n /** Placeholder element for drag operations */\n #placeholder: HTMLDivElement | null = null;\n\n /** Whether placeholder is currently in the DOM */\n #placeholderInDom = false;\n\n /** ResizeObserver for dynamic height measurement */\n #resizeObserver: ResizeObserver | null = null;\n\n /** Map from observed HTMLElement to its trackBy key (reset with each new observer) */\n #observedElements = new WeakMap<HTMLElement, unknown>();\n\n // ========== Inputs ==========\n\n /** The array of items to iterate over */\n vdndVirtualForOf = input.required<T[]>();\n\n /**\n * Height of each item in pixels (used as estimate in dynamic mode).\n * Optional when inside a viewport component — inherited from the viewport's strategy.\n */\n vdndVirtualForItemHeight = input<number>();\n\n /** Track-by function for efficient updates */\n vdndVirtualForTrackBy = input.required<(index: number, item: T) => unknown>();\n\n /** Number of items to render outside the visible area */\n vdndVirtualForOverscan = input<number>(3);\n\n /**\n * ID of the droppable this directive belongs to.\n * Required for placeholder positioning during drag operations.\n */\n vdndVirtualForDroppableId = input<string>();\n\n /**\n * Enable dynamic item height mode.\n * When true, items are auto-measured via ResizeObserver and `itemHeight`\n * serves as the initial estimate for unmeasured items.\n */\n vdndVirtualForDynamicItemHeight = input<boolean>(false);\n\n // ========== Resolved Values ==========\n\n /**\n * Effective droppable ID — uses explicit input or inherits from parent DroppableDirective.\n */\n readonly #effectiveDroppableId = computed(() => {\n return this.vdndVirtualForDroppableId() ?? this.#droppable?.vdndDroppable() ?? undefined;\n });\n\n // ========== Strategy ==========\n\n /**\n * The virtual scroll strategy.\n * If inside a viewport that has a strategy, use that. Otherwise create our own.\n */\n readonly #strategy = computed<VirtualScrollStrategy>(() => {\n // If viewport provides a strategy, use it (shared state for drag-drop)\n const viewportStrategy = this.#viewport?.strategy;\n if (viewportStrategy) return viewportStrategy;\n\n // Create our own strategy (standalone mode — itemHeight is required)\n const height = this.vdndVirtualForItemHeight();\n if (height === undefined) {\n if (isDevMode()) {\n console.warn(\n '[ngx-virtual-dnd] vdndVirtualFor requires itemHeight when not inside a viewport component ' +\n '(vdnd-virtual-viewport or vdnd-virtual-content). Falling back to 50px.',\n );\n }\n return new FixedHeightStrategy(50);\n }\n return this.vdndVirtualForDynamicItemHeight()\n ? new DynamicHeightStrategy(height)\n : new FixedHeightStrategy(height);\n });\n\n // ========== Placeholder Computed Values ==========\n\n /** Whether the placeholder should be shown in this container */\n readonly #shouldShowPlaceholder = computed(() => {\n const droppableId = this.#effectiveDroppableId();\n if (!droppableId) return false;\n if (!this.#dragState.isDragging()) return false;\n return this.#dragState.activeDroppableId() === droppableId;\n });\n\n /** The placeholder index when placeholder should be shown */\n readonly #placeholderIndex = computed(() => {\n if (!this.#shouldShowPlaceholder()) return -1;\n return this.#dragState.placeholderIndex() ?? -1;\n });\n\n // ========== Computed Values ==========\n\n /** First visible item index */\n readonly #firstVisibleIndex = computed(() => {\n const strategy = this.#strategy();\n // Read version to subscribe to dynamic height changes\n strategy.version();\n return strategy.getFirstVisibleIndex(this.#rowsScrollTop());\n });\n\n /**\n * How far the rows are scrolled. A vdnd-virtual-viewport's rows start contentOffset px down its\n * scroll area, but its scrollTop() is the raw position (scrollBy() relies on it), so subtract the\n * offset here. vdnd-virtual-content's scrollTop() already excludes its offset.\n */\n #rowsScrollTop(): number {\n const scrollTop = this.#scrollContainer.scrollTop();\n const viewport = this.#viewport;\n if (viewport === null || viewport !== this.#offsetRowsViewport) {\n return scrollTop;\n }\n return Math.max(0, scrollTop - viewport.contentOffset());\n }\n\n /** Number of visible items */\n readonly #visibleCount = computed(() => {\n const height = this.#scrollContainer.containerHeight();\n const strategy = this.#strategy();\n strategy.version();\n const startIndex = this.#firstVisibleIndex();\n return strategy.getVisibleCount(startIndex, height);\n });\n\n /** Range of items to render */\n readonly #renderRange = computed(() => {\n const first = this.#firstVisibleIndex();\n const visible = this.#visibleCount();\n const overscan = this.vdndVirtualForOverscan();\n const total = this.vdndVirtualForOf().length;\n\n const start = Math.max(0, first - overscan);\n const end = Math.min(total - 1, first + visible + overscan);\n\n return { start, end };\n });\n\n /** Map of trackBy keys to item indices for quick lookup */\n readonly #itemIndexMap = computed(() => {\n const items = this.vdndVirtualForOf();\n const trackByFn = this.vdndVirtualForTrackBy();\n const map = new Map<unknown, number>();\n for (let i = 0; i < items.length; i++) {\n map.set(trackByFn(i, items[i]), i);\n }\n return map;\n });\n\n /** Index of the dragged item in this list (-1 if not present or not dragging) */\n readonly #draggedItemIndex = computed(() => {\n const draggedItem = this.#dragState.draggedItem();\n if (!draggedItem) return -1;\n\n const byId = this.#itemIndexMap().get(draggedItem.draggableId);\n if (byId !== undefined) {\n return byId;\n }\n\n const data = draggedItem.data as T | null | undefined;\n if (data !== null && data !== undefined) {\n return this.vdndVirtualForOf().indexOf(data);\n }\n\n return -1;\n });\n\n constructor() {\n // Keep strategy item keys in sync\n effect(() => {\n const items = this.vdndVirtualForOf();\n const trackByFn = this.vdndVirtualForTrackBy();\n const keys = items.map((item, i) => trackByFn(i, item));\n this.#strategy().setItemKeys(keys);\n });\n\n // Register strategy with drag index calculator for accurate position lookups\n effect((onCleanup) => {\n const droppableId = this.#effectiveDroppableId();\n const strategy = this.#strategy();\n if (droppableId) {\n this.#dragIndexCalculator.registerStrategy(droppableId, strategy);\n onCleanup(() => this.#dragIndexCalculator.unregisterStrategy(droppableId));\n }\n });\n\n // Set excluded index persistently during same-list drag.\n // This ensures ALL strategy methods (getTotalHeight, getOffsetForIndex, etc.)\n // correctly skip the hidden item — not just findIndexAtOffset.\n effect(() => {\n const strategy = this.#strategy();\n const draggedIndex = this.#draggedItemIndex();\n const droppableId = this.#effectiveDroppableId();\n const sourceDroppableId = this.#dragState.sourceDroppableId();\n const isDragging = this.#dragState.isDragging();\n\n const isSourceList =\n isDragging && droppableId !== undefined && droppableId === sourceDroppableId;\n\n if (isSourceList && draggedIndex >= 0) {\n strategy.setExcludedIndex(draggedIndex);\n } else {\n strategy.setExcludedIndex(null);\n }\n });\n\n // Measure item heights in dynamic height mode: the directive's own input, or the viewport's\n // strategy when inherited. Both can change at runtime, and the strategy is replaced when they\n // do, so this creates, replaces or removes the observer. A new observer reports every\n // rendered item, so a new strategy gets their heights.\n effect((onCleanup) => {\n // Read the strategy first so the effect tracks its replacement even when the input is on\n const strategy = this.#strategy();\n const measure =\n this.vdndVirtualForDynamicItemHeight() || strategy instanceof DynamicHeightStrategy;\n // No ResizeObserver during server rendering\n if (!measure || !this.#isBrowser) {\n return;\n }\n untracked(() => this.#startMeasuring());\n onCleanup(() => this.#stopMeasuring());\n });\n\n // React to changes and update views\n effect(() => {\n this.#updateViews();\n });\n }\n\n ngOnInit(): void {\n // Server rendering: there is no ResizeObserver, and elements added outside the template\n // (spacer, placeholder) would not match the client's DOM during hydration. The browser adds\n // the spacer on init, so the server markup lacks only the list's scroll height until then.\n if (!this.#isBrowser) {\n return;\n }\n\n // Only create spacer when NOT inside a viewport component\n // (viewport provides its own spacer and wrapper positioning)\n if (!this.#useViewportPositioning) {\n this.#updateSpacers();\n }\n\n // Create placeholder element for drag operations\n this.#createPlaceholder();\n }\n\n ngOnDestroy(): void {\n this.#viewPool.forEach((view) => view.destroy());\n this.#activeViews.forEach((view) => view.destroy());\n\n // Clean up spacer element (only if we created one)\n this.#spacer?.remove();\n\n // Clean up placeholder element\n this.#placeholder?.remove();\n\n // Clean up ResizeObserver\n this.#resizeObserver?.disconnect();\n\n this.#shiftAnimator?.cancelAll();\n }\n\n #createShiftAnimator(): ShiftAnimator | null {\n const config = inject(VDND_ANIMATION_CONFIG, { optional: true });\n if (!config) return null;\n return new ShiftAnimator({\n config,\n injector: this.#injector,\n getScrollElement: () => this.#scrollContainer.nativeElement,\n getEntries: () => this.#shiftAnimationEntries(),\n });\n }\n\n /** Rendered item root elements (keyed by trackBy key) plus the placeholder. */\n *#shiftAnimationEntries(): Iterable<ShiftAnimationEntry> {\n for (const [key, view] of this.#activeViews) {\n for (const node of view.rootNodes) {\n if (node instanceof HTMLElement) {\n yield [key, node];\n }\n }\n }\n if (this.#placeholder && this.#placeholderInDom) {\n yield [PLACEHOLDER_KEY, this.#placeholder];\n }\n }\n\n /**\n * Create the placeholder element for drag operations.\n */\n #createPlaceholder(): void {\n const placeholder = document.createElement('div');\n placeholder.className = 'vdnd-drag-placeholder vdnd-drag-placeholder-visible';\n placeholder.style.cssText = 'display: block; pointer-events: none;';\n this.#placeholder = placeholder;\n }\n\n /**\n * Set up spacer element for scroll height.\n */\n #updateSpacers(): void {\n // Create single spacer that maintains total scroll height\n const spacer = document.createElement('div');\n spacer.className = 'vdnd-virtual-for-spacer';\n spacer.style.cssText =\n 'position: absolute; top: 0; left: 0; width: 1px; visibility: hidden; pointer-events: none;';\n\n // Insert spacer before the directive's anchor comment\n const comment = this.#elementRef.nativeElement;\n comment.parentNode?.insertBefore(spacer, comment);\n\n this.#spacer = spacer;\n\n // Update spacer height reactively\n // Must pass injector since we're outside constructor\n effect(\n () => {\n const total = this.vdndVirtualForOf().length;\n const strategy = this.#strategy();\n strategy.version();\n\n // Single spacer with full content height\n spacer.style.height = `${strategy.getTotalHeight(total)}px`;\n },\n { injector: this.#injector },\n );\n }\n\n /** Create the ResizeObserver and observe the items already rendered. */\n #startMeasuring(): void {\n this.#setupResizeObserver();\n for (const [key, view] of this.#activeViews) {\n this.#observeViewElements(view, key);\n }\n }\n\n /** Disconnect the ResizeObserver and forget what it observed. */\n #stopMeasuring(): void {\n this.#resizeObserver?.disconnect();\n this.#resizeObserver = null;\n this.#observedElements = new WeakMap();\n }\n\n /**\n * Set up ResizeObserver for dynamic height measurement.\n */\n #setupResizeObserver(): void {\n this.#ngZone.runOutsideAngular(() => {\n this.#resizeObserver = new ResizeObserver((entries) => {\n const strategy = this.#strategy();\n for (const entry of entries) {\n const element = entry.target as HTMLElement;\n const key = this.#observedElements.get(element);\n if (key === undefined) continue;\n\n const height = entry.borderBoxSize?.[0]?.blockSize ?? element.offsetHeight;\n if (height > 0) {\n strategy.setMeasuredHeight(key, height);\n }\n }\n });\n });\n }\n\n /**\n * Observe an element's root nodes for height changes.\n */\n #observeViewElements(view: EmbeddedViewRef<VirtualForContext<T>>, key: unknown): void {\n if (!this.#resizeObserver) return;\n\n for (const node of view.rootNodes) {\n if (node instanceof HTMLElement) {\n const existingKey = this.#observedElements.get(node);\n if (Object.is(existingKey, key)) {\n continue;\n }\n if (existingKey !== undefined) {\n this.#resizeObserver.unobserve(node);\n }\n this.#observedElements.set(node, key);\n this.#resizeObserver.observe(node);\n }\n }\n }\n\n /**\n * Stop any shift animation on a view about to be pooled — a recycled view must not\n * carry an in-flight offset over to the item it renders next.\n */\n #cancelShiftAnimation(view: EmbeddedViewRef<VirtualForContext<T>>): void {\n if (!this.#shiftAnimator) return;\n\n for (const node of view.rootNodes) {\n if (node instanceof HTMLElement) {\n this.#shiftAnimator.cancel(node);\n }\n }\n }\n\n /**\n * Stop observing an element's root nodes.\n */\n #unobserveViewElements(view: EmbeddedViewRef<VirtualForContext<T>>): void {\n if (!this.#resizeObserver) return;\n\n for (const node of view.rootNodes) {\n if (node instanceof HTMLElement) {\n this.#observedElements.delete(node);\n this.#resizeObserver.unobserve(node);\n }\n }\n }\n\n /**\n * Update the rendered views with true view recycling.\n * Views are kept in the DOM and have their context updated in place when possible.\n */\n #updateViews(): void {\n const items = this.vdndVirtualForOf();\n const { start, end } = this.#renderRange();\n const strategy = this.#strategy();\n strategy.version();\n const placeholderIndex = this.#placeholderIndex();\n const showPlaceholder = this.#shouldShowPlaceholder();\n const draggedIndex = this.#draggedItemIndex();\n const droppableId = this.#effectiveDroppableId();\n const sourceDroppableId = this.#dragState.sourceDroppableId();\n const isSourceList = droppableId ? droppableId === sourceDroppableId : true;\n const shouldKeepDragged =\n this.#dragState.isDragging() &&\n draggedIndex >= 0 &&\n isSourceList &&\n draggedIndex < items.length;\n\n // Snapshot positions before the DOM changes so displaced items can slide\n this.#shiftAnimator?.beforeUpdate(this.#dragState.isDragging(), placeholderIndex);\n\n // Notify viewport of render start index for wrapper positioning\n this.#notifyViewportRenderStart(start);\n\n // 1. Build the list of items to render\n const itemsToRender = this.#calculateItemsToRender({\n items,\n start,\n end,\n showPlaceholder,\n placeholderIndex,\n shouldKeepDragged,\n draggedIndex,\n });\n\n // 2. Reconcile views with the DOM\n const placeholderDomPosition = this.#reconcileViews(itemsToRender, showPlaceholder, strategy);\n\n // 3. Position placeholder in DOM\n this.#positionPlaceholder(showPlaceholder, placeholderDomPosition, strategy, placeholderIndex);\n\n // 4. Trim view pool to prevent memory bloat\n this.#trimViewPool();\n }\n\n /**\n * Notify viewport of render start index for wrapper positioning.\n * With persistent excluded index, getOffsetForIndex already accounts for hidden items.\n */\n #notifyViewportRenderStart(start: number): void {\n if (!this.#useViewportPositioning) return;\n this.#viewport?.setRenderStartIndex(start);\n }\n\n /**\n * Calculate the list of items to render, including placeholder positioning\n * and keeping the dragged item alive when scrolled out of range.\n */\n #calculateItemsToRender(params: {\n items: T[];\n start: number;\n end: number;\n showPlaceholder: boolean;\n placeholderIndex: number;\n shouldKeepDragged: boolean;\n draggedIndex: number;\n }): RenderEntry<T>[] {\n const {\n items,\n start,\n end,\n showPlaceholder,\n placeholderIndex,\n shouldKeepDragged,\n draggedIndex,\n } = params;\n const trackByFn = this.vdndVirtualForTrackBy();\n const itemsToRender: RenderEntry<T>[] = [];\n\n // Track placeholder insertion with a flag instead of re-scanning itemsToRender\n // with `.some()` on every iteration (which made the build loop O(n²)).\n let placeholderInserted = false;\n\n // Build render list for visible range\n for (let i = start; i <= end && i < items.length; i++) {\n // Insert placeholder before item at placeholderIndex\n if (showPlaceholder && placeholderIndex === i && !placeholderInserted) {\n itemsToRender.push({\n type: 'placeholder',\n key: PLACEHOLDER_KEY,\n context: null,\n visualIndex: placeholderIndex,\n });\n placeholderInserted = true;\n }\n\n const item = items[i];\n itemsToRender.push({\n type: 'item',\n key: trackByFn(i, item),\n context: {\n $implicit: item,\n index: i,\n first: i === start,\n last: i === end || i === items.length - 1,\n count: items.length,\n },\n visualIndex: i,\n });\n }\n\n // Add placeholder at end if needed\n if (showPlaceholder && placeholderIndex >= items.length && !placeholderInserted) {\n itemsToRender.push({\n type: 'placeholder',\n key: PLACEHOLDER_KEY,\n context: null,\n visualIndex: placeholderIndex,\n });\n }\n\n // Keep dragged item view alive when scrolled out of range\n if (shouldKeepDragged && (draggedIndex < start || draggedIndex > end)) {\n const draggedItem = items[draggedIndex];\n const draggedKey = trackByFn(draggedIndex, draggedItem);\n const alreadyRendered = itemsToRender.some(\n (entry) => entry.type === 'item' && entry.key === draggedKey,\n );\n if (!alreadyRendered) {\n itemsToRender.push({\n type: 'item',\n key: draggedKey,\n context: {\n $implicit: draggedItem,\n index: draggedIndex,\n first: draggedIndex === 0,\n last: draggedIndex === items.length - 1,\n count: items.length,\n },\n visualIndex: draggedIndex,\n });\n }\n }\n\n return itemsToRender;\n }\n\n /**\n * Reconcile views with the calculated items to render.\n * Moves unused views to pool, updates existing views, creates new views as needed.\n * Returns the DOM position where placeholder should be inserted.\n */\n #reconcileViews(\n itemsToRender: RenderEntry<T>[],\n showPlaceholder: boolean,\n strategy: VirtualScrollStrategy,\n ): number {\n // Determine which keys we need\n const neededKeys = new Set(\n itemsToRender.filter((r) => r.type === 'item').map((item) => item.key),\n );\n\n // Move unused views to pool\n for (const [key, view] of this.#activeViews) {\n if (!neededKeys.has(key)) {\n const index = this.#viewContainer.indexOf(view);\n if (index >= 0) {\n this.#viewContainer.detach(index);\n }\n this.#unobserveViewElements(view);\n this.#cancelShiftAnimation(view);\n this.#viewPool.push(view);\n this.#activeViews.delete(key);\n }\n }\n\n // Remove placeholder from DOM if not needed\n if (!showPlaceholder && this.#placeholderInDom && this.#placeholder) {\n this.#placeholder.remove();\n this.#placeholderInDom = false;\n }\n\n // Process items and track placeholder position\n let viewContainerIndex = 0;\n let placeholderDomPosition = -1;\n const renderedKeys = new Set<unknown>();\n\n for (const entry of itemsToRender) {\n if (entry.type === 'placeholder') {\n placeholderDomPosition = viewContainerIndex;\n continue;\n }\n\n if (renderedKeys.has(entry.key)) {\n this.#warnDuplicateTrackByKey(entry.key);\n continue;\n }\n renderedKeys.add(entry.key);\n\n const view = this.#getOrCreateView(entry.key, entry.context!);\n\n // Ensure view is at correct position in ViewContainerRef\n const currentIndex = this.#viewContainer.indexOf(view);\n if (currentIndex !== viewContainerIndex) {\n const targetIndex = this.#getSafeViewContainerIndex(currentIndex, viewContainerIndex);\n if (currentIndex >= 0) {\n if (currentIndex !== targetIndex) {\n this.#viewContainer.move(view, targetIndex);\n }\n } else {\n this.#viewContainer.insert(view, targetIndex);\n }\n }\n\n // Apply absolute positioning when not using viewport wrapper\n if (!this.#useViewportPositioning) {\n const offset = strategy.getOffsetForIndex(entry.visualIndex);\n this.#applyAbsolutePositioning(view, offset);\n }\n\n // Observe for dynamic height measurement\n if (this.#resizeObserver) {\n this.#observeViewElements(view, entry.key);\n }\n\n viewContainerIndex++;\n }\n\n return placeholderDomPosition;\n }\n\n /**\n * Clamp target indices for move/insert to avoid out-of-range operations when\n * reconciliation is given invalid duplicate keys or transiently inconsistent view state.\n */\n #getSafeViewContainerIndex(currentIndex: number, requestedIndex: number): number {\n const length = this.#viewContainer.length;\n\n if (currentIndex >= 0) {\n if (length <= 1) return 0;\n return Math.min(requestedIndex, length - 1);\n }\n\n return Math.min(requestedIndex, length);\n }\n\n /**\n * Duplicate trackBy keys cannot be reconciled to distinct views.\n * Warn in dev mode and skip duplicates to prevent container corruption.\n */\n #warnDuplicateTrackByKey(key: unknown): void {\n if (isDevMode()) {\n console.warn(\n `[ngx-virtual-dnd] Duplicate trackBy key detected in vdndVirtualFor: ${String(key)}. ` +\n 'Skipping duplicate item to avoid view reconciliation errors.',\n );\n }\n }\n\n /**\n * Get an existing view or create/recycle one from the pool.\n */\n #getOrCreateView(\n key: unknown,\n context: VirtualForContext<T>,\n ): EmbeddedViewRef<VirtualForContext<T>> {\n let view = this.#activeViews.get(key);\n\n if (view) {\n // Update existing view context\n Object.assign(view.context, context);\n view.markForCheck();\n } else {\n // Try pool first, then create new\n view = this.#viewPool.pop();\n if (view) {\n Object.assign(view.context, context);\n view.markForCheck();\n } else {\n view = this.#templateRef.createEmbeddedView(context);\n }\n this.#activeViews.set(key, view);\n }\n\n return view;\n }\n\n /**\n * Apply absolute positioning styles to a view's root nodes.\n */\n #applyAbsolutePositioning(view: EmbeddedViewRef<VirtualForContext<T>>, topOffset: number): void {\n for (const node of view.rootNodes) {\n if (node instanceof HTMLElement) {\n node.style.position = 'absolute';\n node.style.top = `${topOffset}px`;\n node.style.left = '0';\n node.style.right = '0';\n }\n }\n }\n\n /**\n * Position the placeholder element in the DOM at the correct index.\n */\n #positionPlaceholder(\n showPlaceholder: boolean,\n placeholderDomPosition: number,\n strategy: VirtualScrollStrategy,\n placeholderIndex: number,\n ): void {\n if (!showPlaceholder || !this.#placeholder || placeholderDomPosition < 0) {\n return;\n }\n\n // Use the dragged item's height if available, otherwise use strategy height\n const draggedItemHeight = this.#dragState.draggedItem()?.height;\n const height = draggedItemHeight ?? strategy.getItemHeight(placeholderIndex);\n this.#placeholder.style.height = `${height}px`;\n\n const container = this.#viewContainer.element.nativeElement.parentElement;\n if (!container) return;\n\n // The placeholder goes immediately before the item view at placeholderDomPosition\n // (the reconcile pass counts item views only, so this index maps directly to a\n // ViewContainerRef view). Reading the reference node from that view avoids\n // re-querying and filtering container.children on every placeholder move.\n const insertBeforeEl = this.#getViewReferenceNode(placeholderDomPosition);\n\n if (!this.#placeholderInDom) {\n // First insertion\n if (insertBeforeEl) {\n container.insertBefore(this.#placeholder, insertBeforeEl);\n } else {\n container.appendChild(this.#placeholder);\n }\n this.#placeholderInDom = true;\n } else {\n // Move to correct position if needed\n const currentNextSibling = this.#placeholder.nextElementSibling;\n if (insertBeforeEl !== currentNextSibling) {\n if (insertBeforeEl) {\n container.insertBefore(this.#placeholder, insertBeforeEl);\n } else {\n container.appendChild(this.#placeholder);\n }\n }\n }\n }\n\n /**\n * Resolve the DOM node the placeholder should be inserted before, given the\n * item-view index produced by the reconcile pass. Returns null when the index\n * is past the last view (placeholder belongs at the end → append).\n */\n #getViewReferenceNode(viewIndex: number): Element | null {\n if (viewIndex < 0 || viewIndex >= this.#viewContainer.length) {\n return null;\n }\n const view = this.#viewContainer.get(viewIndex) as\n | EmbeddedViewRef<VirtualForContext<T>>\n | null\n | undefined;\n if (!view) {\n return null;\n }\n for (const node of view.rootNodes) {\n if (node instanceof HTMLElement) {\n return node;\n }\n }\n return null;\n }\n\n /**\n * Trim the view pool to prevent memory bloat, keeping a reasonable buffer.\n */\n #trimViewPool(): void {\n const maxPoolSize = 10;\n while (this.#viewPool.length > maxPoolSize) {\n const view = this.#viewPool.pop();\n view?.destroy();\n }\n }\n\n /**\n * Static method for Angular's structural directive microsyntax.\n */\n static ngTemplateContextGuard<T>(\n _dir: VirtualForDirective<T>,\n _ctx: unknown,\n ): _ctx is VirtualForContext<T> {\n return true;\n }\n}\n","import { isDevMode, untracked, type WritableSignal } from '@angular/core';\nimport { DropEvent } from '../models/drag-drop.models';\n\n/**\n * Moves an item between signal-based lists based on a drop event.\n * Handles both same-list reordering and cross-list moves.\n *\n * @example\n * ```typescript\n * // In your component:\n * readonly list1 = signal<Item[]>([...]);\n * readonly list2 = signal<Item[]>([...]);\n *\n * onDrop(event: DropEvent): void {\n * moveItem(event, {\n * 'list-1': this.list1,\n * 'list-2': this.list2,\n * });\n * }\n * ```\n *\n * @param event The drop event from the droppable directive\n * @param lists A map of droppable IDs to their corresponding WritableSignal arrays\n */\nexport function moveItem<T>(event: DropEvent, lists: Record<string, WritableSignal<T[]>>): void {\n const sourceList = lists[event.source.droppableId];\n const destList = lists[event.destination.droppableId];\n\n if (!sourceList || !destList) {\n if (isDevMode()) {\n console.warn(\n `[ngx-virtual-dnd] [moveItem] Could not find list for droppable \"${event.source.droppableId}\" or \"${event.destination.droppableId}\"`,\n );\n }\n return;\n }\n\n const sourceIndex = event.source.index;\n const destIndex = event.destination.index;\n\n // Same list reorder\n if (event.source.droppableId === event.destination.droppableId) {\n reorderItems(event, sourceList);\n return;\n }\n\n // Cross-list move. Read untracked, as in reorderItems: an effect that applies the drop must\n // not depend on the lists it changes.\n const item = untracked(sourceList)[sourceIndex];\n\n if (item === undefined) {\n if (isDevMode()) {\n console.warn(`[ngx-virtual-dnd] [moveItem] Could not find item at index ${sourceIndex}`);\n }\n return;\n }\n\n // Remove from source\n sourceList.update((items) => {\n const newItems = [...items];\n newItems.splice(sourceIndex, 1);\n return newItems;\n });\n\n // Insert at destination\n destList.update((items) => {\n const newItems = [...items];\n newItems.splice(destIndex, 0, item);\n return newItems;\n });\n}\n\n/**\n * Reorders items within a single signal-based list.\n *\n * @example\n * ```typescript\n * readonly items = signal<Item[]>([...]);\n *\n * onDrop(event: DropEvent): void {\n * reorderItems(event, this.items);\n * }\n * ```\n *\n * @param event The drop event from the droppable directive\n * @param list The WritableSignal array to reorder\n */\nexport function reorderItems<T>(event: DropEvent, list: WritableSignal<T[]>): void {\n const sourceIndex = event.source.index;\n const destIndex = event.destination.index;\n\n // No-op if same position\n if (sourceIndex === destIndex) {\n return;\n }\n\n // The list may have changed during the drag; never splice in a missing item as undefined.\n // Read untracked: from an effect, a tracked read would make the effect re-run on this reorder.\n if (untracked(list)[sourceIndex] === undefined) {\n if (isDevMode()) {\n console.warn(`[ngx-virtual-dnd] [reorderItems] Could not find item at index ${sourceIndex}`);\n }\n return;\n }\n\n list.update((items) => {\n const newItems = [...items];\n const [removed] = newItems.splice(sourceIndex, 1);\n\n // Note: destination.index from DropEvent is already adjusted for same-list\n // reordering by DroppableDirective.#handleDrop(), so we use it directly.\n newItems.splice(destIndex, 0, removed);\n return newItems;\n });\n}\n\n/**\n * Applies a move operation immutably, returning new array objects.\n * Useful for state management patterns that require immutable updates.\n *\n * @example\n * ```typescript\n * onDrop(event: DropEvent): void {\n * const { list1, list2 } = applyMove(event, {\n * 'list-1': this.list1,\n * 'list-2': this.list2,\n * });\n * // Use the returned arrays with your state management\n * }\n * ```\n *\n * @param event The drop event from the droppable directive\n * @param lists A map of droppable IDs to their corresponding arrays\n * @returns A new object with the same keys but updated arrays\n */\nexport function applyMove<T>(event: DropEvent, lists: Record<string, T[]>): Record<string, T[]> {\n const result = { ...lists };\n const sourceKey = event.source.droppableId;\n const destKey = event.destination.droppableId;\n const sourceIndex = event.source.index;\n const destIndex = event.destination.index;\n\n const sourceItems = [...(lists[sourceKey] ?? [])];\n const item = sourceItems[sourceIndex];\n\n if (item === undefined) {\n return result;\n }\n\n // Same list reorder\n // Note: destination.index from DropEvent is already adjusted for same-list\n // reordering by DroppableDirective.#handleDrop(), so we use it directly.\n if (sourceKey === destKey) {\n const [removed] = sourceItems.splice(sourceIndex, 1);\n sourceItems.splice(destIndex, 0, removed);\n result[sourceKey] = sourceItems;\n return result;\n }\n\n // Cross-list move\n const destItems = [...(lists[destKey] ?? [])];\n sourceItems.splice(sourceIndex, 1);\n destItems.splice(destIndex, 0, item);\n\n result[sourceKey] = sourceItems;\n result[destKey] = destItems;\n\n return result;\n}\n\n/**\n * Checks if a drop event represents a no-op (item dropped in its original position).\n * Useful for skipping unnecessary state updates.\n *\n * @example\n * ```typescript\n * onDrop(event: DropEvent): void {\n * if (isNoOpDrop(event)) {\n * return; // No action needed\n * }\n * moveItem(event, this.lists);\n * }\n * ```\n *\n * @param event The drop event to check\n * @returns true if the drop would result in no change\n */\nexport function isNoOpDrop(event: DropEvent): boolean {\n return (\n event.source.droppableId === event.destination.droppableId &&\n event.source.index === event.destination.index\n );\n}\n\n/**\n * Creates a new list with the item inserted at the specified index.\n * Low-level utility for custom implementations.\n *\n * @param list The source array\n * @param item The item to insert\n * @param index The index to insert at\n * @returns A new array with the item inserted\n */\nexport function insertAt<T>(list: T[], item: T, index: number): T[] {\n const result = [...list];\n result.splice(index, 0, item);\n return result;\n}\n\n/**\n * Creates a new list with the item at the specified index removed.\n * Low-level utility for custom implementations.\n *\n * @param list The source array\n * @param index The index to remove\n * @returns A new array with the item removed\n */\nexport function removeAt<T>(list: T[], index: number): T[] {\n const result = [...list];\n result.splice(index, 1);\n return result;\n}\n","// Models\nexport * from './models/drag-drop.models';\nexport type { VirtualScrollStrategy } from './models/virtual-scroll-strategy';\n\n// Strategies\nexport { FixedHeightStrategy } from './strategies/fixed-height.strategy';\nexport { DynamicHeightStrategy } from './strategies/dynamic-height.strategy';\n\n// Tokens\nexport { VDND_SCROLL_CONTAINER } from './tokens/scroll-container.token';\nexport type { VdndScrollContainer } from './tokens/scroll-container.token';\nexport { VDND_VIRTUAL_VIEWPORT } from './tokens/virtual-viewport.token';\nexport type { VdndVirtualViewport } from './tokens/virtual-viewport.token';\nexport { VDND_ANIMATION_CONFIG } from './tokens/animation-config.token';\nexport type { VdndAnimationConfig } from './tokens/animation-config.token';\n\n// Services\nexport { DragStateService } from './services/drag-state.service';\nexport { PositionCalculatorService } from './services/position-calculator.service';\nexport { AutoScrollService } from './services/auto-scroll.service';\nexport type { AutoScrollConfig } from './services/auto-scroll.service';\nexport { ElementCloneService } from './services/element-clone.service';\nexport { KeyboardDragService } from './services/keyboard-drag.service';\nexport { OverlayContainerService } from './services/overlay-container.service';\n\n// Components\nexport { VirtualScrollContainerComponent } from './components/virtual-scroll-container.component';\nexport type { VirtualScrollItemContext } from './components/virtual-scroll-container.component';\nexport { DragPreviewComponent } from './components/drag-preview.component';\nexport type { DragPreviewContext } from './components/drag-preview.component';\nexport { PlaceholderComponent } from './components/placeholder.component';\nexport type { PlaceholderContext } from './components/placeholder.component';\nexport { DragPlaceholderComponent } from './components/drag-placeholder.component';\nexport { VirtualSortableListComponent } from './components/virtual-sortable-list.component';\nexport { VirtualViewportComponent } from './components/virtual-viewport.component';\nexport { VirtualContentComponent } from './components/virtual-content.component';\n\n// Directives\nexport { DraggableDirective } from './directives/draggable.directive';\nexport { DroppableDirective } from './directives/droppable.directive';\nexport { DroppableGroupDirective, VDND_GROUP_TOKEN } from './directives/droppable-group.directive';\nexport type { VdndGroupContext } from './directives/droppable-group.directive';\nexport { ScrollableDirective } from './directives/scrollable.directive';\nexport { VirtualForDirective } from './directives/virtual-for.directive';\nexport type { VirtualForContext } from './directives/virtual-for.directive';\nexport { ContentHeaderDirective } from './directives/content-header.directive';\n\n// Utilities\nexport {\n moveItem,\n reorderItems,\n applyMove,\n isNoOpDrop,\n insertAt,\n removeAt,\n} from './utils/drop-helpers';\n","/*\n * Public API Surface of ngx-virtual-dnd\n */\n\nexport * from './lib/index';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ngx-virtual-dnd.mjs","sources":["../../../projects/ngx-virtual-dnd/src/lib/models/drag-drop.models.ts","../../../projects/ngx-virtual-dnd/src/lib/strategies/fixed-height.strategy.ts","../../../projects/ngx-virtual-dnd/src/lib/utils/height-cache.ts","../../../projects/ngx-virtual-dnd/src/lib/strategies/dynamic-height.strategy.ts","../../../projects/ngx-virtual-dnd/src/lib/tokens/scroll-container.token.ts","../../../projects/ngx-virtual-dnd/src/lib/tokens/virtual-viewport.token.ts","../../../projects/ngx-virtual-dnd/src/lib/tokens/animation-config.token.ts","../../../projects/ngx-virtual-dnd/src/lib/services/droppable-registry.service.ts","../../../projects/ngx-virtual-dnd/src/lib/services/drag-state.service.ts","../../../projects/ngx-virtual-dnd/src/lib/services/position-calculator.service.ts","../../../projects/ngx-virtual-dnd/src/lib/services/drag-scheduler.service.ts","../../../projects/ngx-virtual-dnd/src/lib/services/auto-scroll.service.ts","../../../projects/ngx-virtual-dnd/src/lib/services/element-clone.service.ts","../../../projects/ngx-virtual-dnd/src/lib/services/keyboard-drag.service.ts","../../../projects/ngx-virtual-dnd/src/lib/services/overlay-container.service.ts","../../../projects/ngx-virtual-dnd/src/lib/services/drag-index-calculator.service.ts","../../../projects/ngx-virtual-dnd/src/lib/components/drag-placeholder.component.ts","../../../projects/ngx-virtual-dnd/src/lib/utils/dom-signal-bindings.ts","../../../projects/ngx-virtual-dnd/src/lib/utils/auto-scroll-registration.ts","../../../projects/ngx-virtual-dnd/src/lib/strategies/strategy-items.ts","../../../projects/ngx-virtual-dnd/src/lib/utils/attribute-selectors.ts","../../../projects/ngx-virtual-dnd/src/lib/utils/shift-animator.ts","../../../projects/ngx-virtual-dnd/src/lib/utils/drop-animator.ts","../../../projects/ngx-virtual-dnd/src/lib/components/virtual-scroll-container.component.ts","../../../projects/ngx-virtual-dnd/src/lib/components/drag-preview.component.ts","../../../projects/ngx-virtual-dnd/src/lib/components/placeholder.component.ts","../../../projects/ngx-virtual-dnd/src/lib/directives/droppable-group.directive.ts","../../../projects/ngx-virtual-dnd/src/lib/utils/group-resolution.ts","../../../projects/ngx-virtual-dnd/src/lib/utils/drop-index-normalization.ts","../../../projects/ngx-virtual-dnd/src/lib/directives/droppable.directive.ts","../../../projects/ngx-virtual-dnd/src/lib/components/virtual-sortable-list.component.ts","../../../projects/ngx-virtual-dnd/src/lib/components/virtual-viewport.component.ts","../../../projects/ngx-virtual-dnd/src/lib/directives/content-header.directive.ts","../../../projects/ngx-virtual-dnd/src/lib/components/virtual-content.component.ts","../../../projects/ngx-virtual-dnd/src/lib/handlers/keyboard-drag.handler.ts","../../../projects/ngx-virtual-dnd/src/lib/utils/interactive-elements.ts","../../../projects/ngx-virtual-dnd/src/lib/handlers/pointer-drag.handler.ts","../../../projects/ngx-virtual-dnd/src/lib/directives/draggable.directive.ts","../../../projects/ngx-virtual-dnd/src/lib/directives/scrollable.directive.ts","../../../projects/ngx-virtual-dnd/src/lib/directives/virtual-for.directive.ts","../../../projects/ngx-virtual-dnd/src/lib/utils/drop-helpers.ts","../../../projects/ngx-virtual-dnd/src/lib/index.ts","../../../projects/ngx-virtual-dnd/src/public-api.ts","../../../projects/ngx-virtual-dnd/src/ngx-virtual-dnd.ts"],"sourcesContent":["/**\n * Represents the item currently being dragged.\n */\nexport interface DraggedItem {\n /** Unique identifier for the draggable item */\n draggableId: string;\n /** ID of the droppable container the item originated from */\n droppableId: string;\n /** Reference to the dragged element */\n element: HTMLElement;\n /** Cloned element for use in drag preview (auto-generated) */\n clonedElement?: HTMLElement;\n /** Height of the dragged element in pixels */\n height: number;\n /** Width of the dragged element in pixels */\n width: number;\n /** Optional user-provided data associated with the item */\n data?: unknown;\n}\n\n/**\n * Current position of the cursor during drag.\n */\nexport interface CursorPosition {\n x: number;\n y: number;\n}\n\n/**\n * Offset from cursor to the top-left corner of the dragged element.\n * Used to maintain grab position during drag.\n */\nexport interface GrabOffset {\n x: number;\n y: number;\n}\n\n/**\n * Complete state of the drag-and-drop system.\n */\nexport interface DragState {\n /** Whether a drag operation is currently in progress */\n isDragging: boolean;\n /** Information about the item being dragged */\n draggedItem: DraggedItem | null;\n /** ID of the droppable where the drag started */\n sourceDroppableId: string | null;\n /** Original index of the dragged item in the source list */\n sourceIndex: number | null;\n /** ID of the droppable currently being hovered over */\n activeDroppableId: string | null;\n /**\n * `END_OF_LIST` while a droppable is targeted, otherwise null.\n * @deprecated It never identifies an item. Use `placeholderIndex`. Will be removed in the next\n * major version.\n */\n placeholderId: string | null;\n /** Index where the placeholder should be inserted */\n placeholderIndex: number | null;\n /** Current cursor position */\n cursorPosition: CursorPosition | null;\n /** Offset from cursor to element top-left (for maintaining grab position) */\n grabOffset: GrabOffset | null;\n /** Position when drag started (for axis locking) */\n initialPosition: CursorPosition | null;\n /** Axis to freeze ('x' = X frozen → vertical-only, 'y' = Y frozen → horizontal-only) */\n lockAxis: 'x' | 'y' | null;\n /** Whether this is a keyboard-initiated drag */\n isKeyboardDrag: boolean;\n /** Target index during keyboard navigation */\n keyboardTargetIndex: number | null;\n}\n\n/**\n * Event emitted when a drag operation starts.\n */\nexport interface DragStartEvent {\n /** Unique identifier for the draggable item */\n draggableId: string;\n /** ID of the droppable container the item originated from */\n droppableId: string;\n /** Optional user-provided data associated with the item */\n data?: unknown;\n /** Position where the drag started */\n position: CursorPosition;\n /** 0-indexed position in the source list (for screen reader announcements) */\n sourceIndex: number;\n}\n\n/**\n * Source information for a drop event.\n */\nexport interface DropSource {\n /** Unique identifier for the draggable item */\n draggableId: string;\n /** ID of the droppable container the item originated from */\n droppableId: string;\n /** Original index in the source list */\n index: number;\n /** Optional user-provided data associated with the item */\n data?: unknown;\n}\n\n/**\n * Destination information for a drop event.\n */\nexport interface DropDestination {\n /** ID of the droppable container receiving the item */\n droppableId: string;\n /**\n * The library always sets `END_OF_LIST`.\n * @deprecated It never identifies an item. Use `index` for the insertion position. Will be\n * removed in the next major version.\n */\n placeholderId: string;\n /** Target index in the destination list */\n index: number;\n /** Optional user-provided data associated with the droppable */\n data?: unknown;\n}\n\n/**\n * Event emitted by the destination droppable when an item is dropped on it: at release,\n * right after the dragged item's `DragEndEvent` and before the next render.\n */\nexport interface DropEvent {\n /** Information about where the item came from */\n source: DropSource;\n /** Information about where the item is going */\n destination: DropDestination;\n}\n\n/**\n * Event emitted by a droppable each time the placeholder moves within it during a drag,\n * i.e. whenever items are displaced. Useful for haptic feedback on every step.\n *\n * Indexes use the same convention as `DropEvent.destination.index` (the insertion index\n * the item would get if dropped now). Not emitted for the placeholder's initial position\n * at drag start, nor when the placeholder leaves this droppable.\n */\nexport interface PlaceholderMoveEvent {\n /** Unique identifier for the dragged item */\n draggableId: string;\n /** ID of the droppable container the item originated from */\n sourceDroppableId: string;\n /** ID of the droppable the placeholder moved within */\n droppableId: string;\n /**\n * Previous insertion index in this droppable, or `null` when the placeholder just entered\n * it from elsewhere. For the first move in the source list this is the item's own index.\n */\n previousIndex: number | null;\n /** New insertion index in this droppable */\n currentIndex: number;\n /** Optional user-provided data associated with the dragged item */\n data?: unknown;\n}\n\n/**\n * Event emitted when a drag operation ends (including cancel).\n */\nexport interface DragEndEvent {\n /** Unique identifier for the draggable item */\n draggableId: string;\n /** ID of the droppable container the item originated from */\n droppableId: string;\n /**\n * Whether the drag was cancelled: Escape, Tab during a keyboard drag, or, during a pointer\n * drag, the window losing focus, the page being hidden or the system cancelling the touch\n * (`touchcancel`). Releasing over no valid\n * target (outside any droppable, or over a disabled droppable) is NOT a cancel —\n * it reports `cancelled: false` with `destinationIndex: null`. Branch on\n * `destinationIndex === null` to detect \"no drop occurred\".\n */\n cancelled: boolean;\n /** Optional user-provided data associated with the item */\n data?: unknown;\n /** Original 0-indexed position in source list (for cancel announcements) */\n sourceIndex: number;\n /**\n * Final 0-indexed insertion position, or `null` when there is no valid drop target —\n * a cancelled drag, a release outside every droppable, or a release over a disabled\n * droppable. A non-null value pairs with the `DropEvent` the destination emits right after.\n */\n destinationIndex: number | null;\n}\n\n/**\n * Initial state for the drag state service.\n */\nexport const INITIAL_DRAG_STATE: DragState = {\n isDragging: false,\n draggedItem: null,\n sourceDroppableId: null,\n sourceIndex: null,\n activeDroppableId: null,\n placeholderId: null,\n placeholderIndex: null,\n cursorPosition: null,\n grabOffset: null,\n initialPosition: null,\n lockAxis: null,\n isKeyboardDrag: false,\n keyboardTargetIndex: null,\n};\n\n/**\n * The value of every `placeholderId` the library sets. Positions are reported as indexes\n * (`placeholderIndex`, `DropDestination.index`).\n * @deprecated Goes with the deprecated `placeholderId` fields. Use the indexes. Will be removed in\n * the next major version.\n */\nexport const END_OF_LIST = 'END_OF_LIST';\n","import { signal } from '@angular/core';\nimport type { VirtualScrollStrategy } from '../models/virtual-scroll-strategy';\n\n/**\n * Fixed-height virtual scroll strategy.\n *\n * Wraps the existing `index * itemHeight` math with zero overhead — no cache,\n * no measurement. This is the default strategy used when `dynamicItemHeight`\n * is not enabled.\n */\nexport class FixedHeightStrategy implements VirtualScrollStrategy {\n readonly #itemHeight: number;\n\n /** Excluded index during same-list drag (-1 = none) */\n #excludedIndex = -1;\n\n /** Logical item count from setItemKeys (used by drag index calculator) */\n #itemCount = 0;\n\n /** Version signal — bumps when exclusion changes */\n readonly #version = signal(0);\n readonly version = this.#version.asReadonly();\n\n constructor(itemHeight: number) {\n this.#itemHeight = itemHeight;\n }\n\n getTotalHeight(itemCount: number): number {\n return itemCount * this.#itemHeight;\n }\n\n getFirstVisibleIndex(scrollTop: number): number {\n if (this.#itemHeight <= 0) return 0;\n return Math.floor(scrollTop / this.#itemHeight);\n }\n\n getVisibleCount(_startIndex: number, containerHeight: number): number {\n if (containerHeight <= 0 || this.#itemHeight <= 0) return 0;\n return Math.ceil(containerHeight / this.#itemHeight);\n }\n\n getOffsetForIndex(index: number): number {\n if (this.#excludedIndex >= 0 && index > this.#excludedIndex) {\n return (index - 1) * this.#itemHeight;\n }\n return index * this.#itemHeight;\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n getItemHeight(index: number): number {\n return this.#itemHeight;\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n setMeasuredHeight(key: unknown, height: number): void {\n // No-op for fixed height strategy\n }\n\n setItemKeys(keys: unknown[]): void {\n this.setItemCount(keys.length);\n }\n\n /**\n * Set the item count: all this strategy needs of the keys, so the library's containers skip\n * computing them.\n * @internal\n */\n setItemCount(count: number): void {\n if (this.#itemCount !== count) {\n this.#itemCount = count;\n this.#version.update((v) => v + 1);\n }\n }\n\n setExcludedIndex(index: number | null): void {\n const newIndex = index ?? -1;\n if (this.#excludedIndex !== newIndex) {\n this.#excludedIndex = newIndex;\n this.#version.update((v) => v + 1);\n }\n }\n\n findIndexAtOffset(offset: number): number {\n if (this.#itemHeight <= 0) return 0;\n const visualIndex = Math.floor(offset / this.#itemHeight);\n // When an item is excluded (same-list drag), visual indices at or past\n // the excluded position map to logical index + 1\n if (this.#excludedIndex >= 0 && visualIndex >= this.#excludedIndex) {\n return visualIndex + 1;\n }\n return visualIndex;\n }\n\n getItemCount(): number {\n return this.#itemCount;\n }\n}\n","/**\n * Cache for measured item heights in dynamic virtual scrolling.\n *\n * Tracks heights by trackBy key (survives reordering). Maintains a cumulative\n * offset prefix-sum array and binary searches it for scroll-to-index lookups.\n *\n * The prefix sums are brought up to date lazily and only as far as a lookup needs:\n * a height change invalidates the offsets from that item on, and the next lookup\n * recomputes them up to the item it asks about. Measurements land on the rendered\n * rows and lookups ask about the rows in view, so while scrolling a long list each\n * frame recomputes a few rows' offsets instead of the whole list. The total height\n * is kept as a running sum, so the spacer height needs no prefix sums between key\n * changes.\n *\n * This is a plain class (not a service) — one instance per virtual scroll.\n */\nexport class HeightCache {\n /** Estimated height used for unmeasured items */\n readonly #estimatedHeight: number;\n\n /** Map from trackBy key to measured height */\n readonly #heightsByKey = new Map<unknown, number>();\n\n /**\n * Current ordered list of trackBy keys (index-aligned with item array). A copy of the array\n * given to `setKeys`, so a caller that changes its array in place and passes it again is seen.\n */\n #keys: unknown[] = [];\n\n /** Index of each key's first occurrence in `#keys` */\n #firstIndexByKey = new Map<unknown, number>();\n\n /** Whether a key occurs more than once in `#keys` (a trackBy misconfiguration) */\n #hasDuplicateKeys = false;\n\n /** Prefix sums: offsets[i] = cumulative height of items 0..i-1 */\n #offsets: number[] = [];\n\n /** Number of leading `#offsets` entries that are up to date */\n #validCount = 0;\n\n /** Sum of the heights of all items in `#keys`, or null until it is next needed */\n #totalHeight: number | null = 0;\n\n /** Index excluded during same-list drag (-1 = none) */\n #excludedIndex = -1;\n\n constructor(estimatedHeight: number) {\n this.#estimatedHeight = estimatedHeight;\n }\n\n /** Number of measured items */\n get measuredCount(): number {\n return this.#heightsByKey.size;\n }\n\n /** Number of logical items in the cache */\n get itemCount(): number {\n return this.#keys.length;\n }\n\n /**\n * Update the ordered list of trackBy keys.\n * This must be called whenever items change order or the array changes.\n */\n setKeys(keys: unknown[]): boolean {\n // The same keys in the same order (an items change that moved no item) leave the offsets and\n // the key index valid: only heights recorded for keys not in the list are forgotten\n if (\n keys.length === this.#keys.length &&\n keys.every((key, index) => Object.is(key, this.#keys[index]))\n ) {\n return this.#forgetHeightsNotIn(this.#firstIndexByKey);\n }\n\n // Filled from the end, so each key keeps its first index. It also serves as the set of keys\n // for pruning, so building it costs no extra pass.\n const firstIndexByKey = new Map<unknown, number>();\n for (let i = keys.length - 1; i >= 0; i--) {\n firstIndexByKey.set(keys[i], i);\n }\n this.#forgetHeightsNotIn(firstIndexByKey);\n\n // Offsets before the first key that changed position are still valid\n let firstChanged = 0;\n const commonLength = Math.min(keys.length, this.#keys.length);\n while (firstChanged < commonLength && Object.is(keys[firstChanged], this.#keys[firstChanged])) {\n firstChanged++;\n }\n\n this.#keys = keys.slice();\n this.#firstIndexByKey = firstIndexByKey;\n this.#hasDuplicateKeys = firstIndexByKey.size < keys.length;\n this.#offsets.length = keys.length;\n this.#validCount = Math.min(this.#validCount, firstChanged);\n this.#totalHeight = null;\n return true;\n }\n\n /**\n * Record a measured height for a trackBy key.\n * @returns true if the height actually changed (triggers version bump)\n */\n setHeight(key: unknown, height: number): boolean {\n const existing = this.#heightsByKey.get(key);\n if (existing === height) return false;\n this.#heightsByKey.set(key, height);\n\n // Only items at or after the key's first position move\n const firstIndex = this.#firstIndexByKey.get(key);\n if (firstIndex !== undefined) {\n this.#validCount = Math.min(this.#validCount, firstIndex);\n const previous = existing ?? this.#estimatedHeight;\n // A key listed twice, or a non-finite height (which a running sum can't take back out),\n // leaves the total to be recomputed from the offsets\n this.#totalHeight =\n this.#totalHeight === null ||\n this.#hasDuplicateKeys ||\n !Number.isFinite(height) ||\n !Number.isFinite(previous)\n ? null\n : this.#totalHeight + height - previous;\n }\n return true;\n }\n\n /**\n * Get the height for a specific index.\n * Returns measured height if available, otherwise the estimated height.\n */\n getHeight(index: number): number {\n if (index < 0 || index >= this.#keys.length) return this.#estimatedHeight;\n const key = this.#keys[index];\n return this.#heightsByKey.get(key) ?? this.#estimatedHeight;\n }\n\n /**\n * Get the pixel offset (top position) for a given item index.\n * Accounts for the excluded index during same-list drag.\n */\n getOffset(index: number): number {\n const count = this.#keys.length;\n\n if (this.#excludedIndex < 0) {\n // No exclusion — direct lookup\n return index < count ? this.#offsetAt(index) : this.#getExactTotalHeight();\n }\n\n // With exclusion: subtract the excluded item's height from offsets\n // at or after the excluded index\n if (index <= this.#excludedIndex) {\n return this.#offsetAt(index) ?? 0;\n }\n\n // index > excludedIndex: offset = raw offset for (index) minus excluded item's height\n const rawOffset = index < count ? this.#offsetAt(index) : this.#getExactTotalHeight();\n const excludedHeight = this.getHeight(this.#excludedIndex);\n return rawOffset - excludedHeight;\n }\n\n /**\n * Get total content height for all items.\n * Does NOT exclude the dragged item — the spacer must maintain full height\n * during same-list drag so sibling content (footers etc.) doesn't shift.\n * Uses O(1) prefix-sum lookup when possible.\n */\n getTotalHeight(itemCount: number): number {\n if (itemCount <= 0) return 0;\n\n const keyCount = this.#keys.length;\n if (keyCount === 0) return itemCount * this.#estimatedHeight;\n\n if (itemCount >= keyCount) {\n // All known items + estimated for any extras\n return this.#getTotalHeightRaw() + (itemCount - keyCount) * this.#estimatedHeight;\n }\n\n // Partial: prefix sum up to itemCount\n return this.#offsetAt(itemCount - 1) + this.getHeight(itemCount - 1);\n }\n\n /**\n * Find the first visible index for a given scrollTop.\n * Uses binary search on the prefix-sum offsets (excluding the excluded item).\n */\n findFirstVisibleIndex(scrollTop: number): number {\n const count = this.#keys.length;\n if (count === 0) return 0;\n\n // Offsets after the excluded item sit its height higher than their raw values, so\n // bring the raw offsets up to date just past scrollTop plus that height\n const excludedHeight = this.#excludedIndex >= 0 ? this.getHeight(this.#excludedIndex) : 0;\n this.#extendPastOffset(scrollTop + excludedHeight);\n\n // Binary search for the last item whose top is at or above scrollTop. Items past the\n // up-to-date offsets start below scrollTop, so the search can stop there.\n let lo = 0;\n let hi = Math.min(count, this.#validCount) - 1;\n let result = 0;\n\n while (lo <= hi) {\n const mid = (lo + hi) >>> 1;\n const offset = this.getOffset(mid);\n if (offset <= scrollTop) {\n result = mid;\n lo = mid + 1;\n } else {\n hi = mid - 1;\n }\n }\n\n return result;\n }\n\n /**\n * Count visible items from startIndex within containerHeight.\n */\n getVisibleCount(startIndex: number, containerHeight: number): number {\n if (containerHeight <= 0) return 0;\n\n const count = this.#keys.length;\n let accumulated = 0;\n let visible = 0;\n let stopIndex = count;\n\n for (let i = startIndex; i < count; i++) {\n if (i === this.#excludedIndex) continue;\n accumulated += this.getHeight(i);\n visible++;\n if (accumulated >= containerHeight) {\n stopIndex = i;\n break;\n }\n }\n\n // Add 1 for partially visible items\n if (visible === 0) return 0;\n const hasMoreItems = stopIndex < count - 1;\n return hasMoreItems ? visible + 1 : visible;\n }\n\n /**\n * Find the item index at a given pixel offset.\n * Used for drag index calculations with variable heights.\n */\n findIndexAtOffset(offset: number): number {\n const count = this.#keys.length;\n if (count === 0) return 0;\n\n if (!Number.isFinite(offset)) {\n return offset < 0 ? 0 : count;\n }\n\n if (offset <= 0) {\n if (this.#excludedIndex === 0) {\n return count > 1 ? 1 : count;\n }\n return 0;\n }\n\n const excludedIndex = this.#excludedIndex;\n if (excludedIndex < 0 || excludedIndex >= count) {\n return this.#findFirstIndexWithBottomPastOffset(offset, 0, count - 1);\n }\n\n const excludedOffset = this.#offsetAt(excludedIndex);\n if (offset < excludedOffset && excludedIndex > 0) {\n return this.#findFirstIndexWithBottomPastOffset(offset, 0, excludedIndex - 1);\n }\n\n if (excludedIndex >= count - 1) {\n return count;\n }\n\n const excludedHeight = this.getHeight(excludedIndex);\n return this.#findFirstIndexWithBottomPastOffset(\n offset + excludedHeight,\n excludedIndex + 1,\n count - 1,\n );\n }\n\n /**\n * Set the excluded index for same-list drag.\n */\n setExcludedIndex(index: number | null): boolean {\n const nextIndex = index ?? -1;\n if (this.#excludedIndex === nextIndex) {\n return false;\n }\n\n this.#excludedIndex = nextIndex;\n return true;\n }\n\n /** Forget the heights of keys not in `keys`. Returns whether it forgot any. */\n #forgetHeightsNotIn(keys: ReadonlyMap<unknown, number>): boolean {\n let forgot = false;\n for (const key of this.#heightsByKey.keys()) {\n if (!keys.has(key)) {\n this.#heightsByKey.delete(key);\n forgot = true;\n }\n }\n return forgot;\n }\n\n /**\n * Find first logical index in [start, end] whose bottom edge is past offset.\n * Returns one-past-end when no match is found.\n */\n #findFirstIndexWithBottomPastOffset(offset: number, start: number, end: number): number {\n if (start > end) {\n return start;\n }\n\n // Items past the up-to-date offsets start below `offset`, so their bottoms are past it\n // too: the answer is at or before the first of them\n this.#extendPastOffset(offset);\n const lastValid = this.#validCount - 1;\n if (start > lastValid) {\n return start;\n }\n\n let lo = start;\n let hi = Math.min(end, lastValid);\n let result = end + 1;\n\n while (lo <= hi) {\n const mid = (lo + hi) >>> 1;\n const midBottom = this.#offsets[mid] + this.getHeight(mid);\n\n if (midBottom > offset) {\n result = mid;\n hi = mid - 1;\n } else {\n lo = mid + 1;\n }\n }\n\n return result;\n }\n\n /**\n * Raw total height without exclusion, from the running sum. With fractional heights it can\n * differ from the prefix sums by rounding, so it is only for the spacer height.\n */\n #getTotalHeightRaw(): number {\n if (this.#keys.length === 0) return 0;\n return this.#totalHeight ?? this.#getExactTotalHeight();\n }\n\n /**\n * Raw total height computed like the offsets (the offset one past the last item), so it\n * compares exactly with them. Re-syncs the running sum.\n */\n #getExactTotalHeight(): number {\n const count = this.#keys.length;\n if (count === 0) return 0;\n this.#extendTo(count, Infinity);\n this.#totalHeight = this.#offsets[count - 1] + this.getHeight(count - 1);\n return this.#totalHeight;\n }\n\n /** The raw offset of an item, bringing the prefix sums up to date as far as it */\n #offsetAt(index: number): number {\n if (index >= this.#validCount) {\n this.#extendTo(index + 1, Infinity);\n }\n return this.#offsets[index];\n }\n\n /**\n * Bring the prefix sums up to date until the last up-to-date item starts past `offset`, or\n * to the end of the list.\n */\n #extendPastOffset(offset: number): void {\n this.#extendTo(this.#keys.length, offset);\n }\n\n /**\n * Bring the first `count` prefix sums up to date, stopping early after the first item that\n * starts past `stopPastOffset`.\n */\n #extendTo(count: number, stopPastOffset: number): void {\n const end = Math.min(count, this.#keys.length);\n let i = this.#validCount;\n if (i >= end || (i > 0 && this.#offsets[i - 1] > stopPastOffset)) {\n return;\n }\n\n let cumulative = i === 0 ? 0 : this.#offsets[i - 1] + this.getHeight(i - 1);\n while (i < end) {\n this.#offsets[i] = cumulative;\n i++;\n if (cumulative > stopPastOffset) {\n break;\n }\n cumulative += this.getHeight(i - 1);\n }\n this.#validCount = i;\n\n if (i === this.#keys.length) {\n // Re-sync the running total with the prefix sums, dropping floating-point drift\n this.#totalHeight = this.#offsets[i - 1] + this.getHeight(i - 1);\n }\n }\n}\n","import { signal, type Signal, type WritableSignal } from '@angular/core';\nimport type { VirtualScrollStrategy } from '../models/virtual-scroll-strategy';\nimport { HeightCache } from '../utils/height-cache';\n\n/**\n * Dynamic-height virtual scroll strategy.\n *\n * Uses a `HeightCache` with prefix-sum offsets and binary search for O(log N)\n * scroll-to-index lookups. Heights are tracked by trackBy key (survive\n * reordering) and auto-measured via ResizeObserver by the directive.\n *\n * The `version` signal bumps whenever heights change, causing dependent\n * computeds to re-evaluate.\n */\nexport class DynamicHeightStrategy implements VirtualScrollStrategy {\n readonly #cache: HeightCache;\n readonly #version: WritableSignal<number> = signal(0);\n\n readonly version: Signal<number> = this.#version.asReadonly();\n\n constructor(estimatedHeight: number) {\n this.#cache = new HeightCache(estimatedHeight);\n }\n\n getTotalHeight(itemCount: number): number {\n // Read version to subscribe to changes\n this.#version();\n return this.#cache.getTotalHeight(itemCount);\n }\n\n getFirstVisibleIndex(scrollTop: number): number {\n this.#version();\n return this.#cache.findFirstVisibleIndex(scrollTop);\n }\n\n getVisibleCount(startIndex: number, containerHeight: number): number {\n this.#version();\n return this.#cache.getVisibleCount(startIndex, containerHeight);\n }\n\n getOffsetForIndex(index: number): number {\n this.#version();\n return this.#cache.getOffset(index);\n }\n\n getItemHeight(index: number): number {\n this.#version();\n return this.#cache.getHeight(index);\n }\n\n setMeasuredHeight(key: unknown, height: number): void {\n const changed = this.#cache.setHeight(key, height);\n if (changed) {\n this.#version.update((v) => v + 1);\n }\n }\n\n setItemKeys(keys: unknown[]): void {\n const changed = this.#cache.setKeys(keys);\n if (changed) {\n this.#version.update((v) => v + 1);\n }\n }\n\n setExcludedIndex(index: number | null): void {\n const changed = this.#cache.setExcludedIndex(index);\n if (changed) {\n this.#version.update((v) => v + 1);\n }\n }\n\n findIndexAtOffset(offset: number): number {\n this.#version();\n return this.#cache.findIndexAtOffset(offset);\n }\n\n getItemCount(): number {\n this.#version();\n return this.#cache.itemCount;\n }\n}\n","import { InjectionToken } from '@angular/core';\n\n/**\n * Interface for a scroll container that can be used with VirtualForDirective.\n * Implement this interface to create custom scroll containers.\n *\n * The scrollTop() and containerHeight() methods should return reactive values\n * (internally backed by signals) so that changes trigger re-computation in\n * the virtual scroll directive.\n */\nexport interface VdndScrollContainer {\n /** The native HTML element that handles scrolling */\n readonly nativeElement: HTMLElement;\n\n /** Current scroll position from top in pixels (reactive) */\n scrollTop(): number;\n\n /** Current container height in pixels (reactive) */\n containerHeight(): number;\n\n /** Scroll to a specific position */\n scrollTo(options: ScrollToOptions): void;\n}\n\n/**\n * Injection token for providing a scroll container to VirtualForDirective.\n *\n * Use the `vdndScrollable` directive to provide this token, or implement\n * `VdndScrollContainer` and provide it manually.\n *\n * @example\n * ```html\n * <div vdndScrollable style=\"overflow: auto; height: 400px;\">\n * <ng-container *vdndVirtualFor=\"let item of items(); itemHeight: 50; trackBy: trackById\">\n * <div>{{ item.name }}</div>\n * </ng-container>\n * </div>\n * ```\n */\nexport const VDND_SCROLL_CONTAINER = new InjectionToken<VdndScrollContainer>(\n 'VDND_SCROLL_CONTAINER'\n);\n","import { InjectionToken } from '@angular/core';\nimport type { VirtualScrollStrategy } from '../models/virtual-scroll-strategy';\n\n/**\n * Interface for a virtual viewport that provides wrapper-based positioning.\n * Components implementing this interface provide a content wrapper with\n * GPU-accelerated transform positioning for efficient virtual scrolling.\n */\nexport interface VdndVirtualViewport {\n /** Current scroll position */\n scrollTop(): number;\n\n /** Height of the viewport container */\n containerHeight(): number;\n\n /** Height of each item in pixels */\n itemHeight(): number;\n\n /** Offset for content below headers (page-level scroll scenarios) */\n contentOffset(): number;\n\n /** The native element of the viewport */\n readonly nativeElement: HTMLElement;\n\n /**\n * Called by VirtualForDirective to inform the viewport of the actual\n * first rendered item index (accounting for overscan). The viewport\n * uses this to position the content wrapper correctly.\n */\n setRenderStartIndex(index: number): void;\n\n /**\n * Get the pixel offset for a given item index.\n * Uses the strategy pattern to support both fixed and dynamic heights.\n */\n getOffsetForIndex(index: number): number;\n\n /**\n * The virtual scroll strategy used by this viewport.\n * Available for drag-drop integration and external consumers.\n */\n readonly strategy: VirtualScrollStrategy | null;\n}\n\n/**\n * Injection token for virtual viewport.\n * VirtualForDirective optionally injects this to detect if it's inside\n * a viewport component that handles wrapper-based positioning.\n */\nexport const VDND_VIRTUAL_VIEWPORT = new InjectionToken<VdndVirtualViewport>(\n 'VDND_VIRTUAL_VIEWPORT',\n);\n\n/**\n * Internal, not exported from the package. Provided by vdnd-virtual-viewport next to\n * VDND_VIRTUAL_VIEWPORT: its rows start contentOffset px down its scroll area while its\n * scrollTop() is the raw position, so VirtualForDirective subtracts the offset when the viewport\n * it injects is this one. A token instead of an instanceof check keeps the viewport component out\n * of apps that don't use it.\n */\nexport const VDND_OFFSET_ROWS_VIEWPORT = new InjectionToken<VdndVirtualViewport>(\n 'VDND_OFFSET_ROWS_VIEWPORT',\n);\n","import { InjectionToken } from '@angular/core';\n\n/**\n * Animation settings for drag-and-drop lists.\n */\nexport interface VdndAnimationConfig {\n /**\n * Duration (ms) of the slide animation played when items are displaced by the\n * placeholder during a drag. `0` disables the animation.\n * @default 200\n */\n shiftDuration?: number;\n\n /**\n * CSS easing function for the shift animation.\n * @default 'cubic-bezier(0.2, 0, 0, 1)'\n */\n shiftEasing?: string;\n\n /**\n * Duration (ms) of the drop animation: on drop or cancel, the drag preview glides into\n * the dropped item's final position instead of disappearing. `0` disables it.\n * @default 200\n */\n dropDuration?: number;\n\n /**\n * CSS easing function for the drop animation.\n * @default 'cubic-bezier(0.2, 0, 0, 1)'\n */\n dropEasing?: string;\n}\n\n/** Default shift animation duration (ms) used when the config omits `shiftDuration`. */\nexport const DEFAULT_SHIFT_DURATION = 200;\n\n/** Default shift animation easing used when the config omits `shiftEasing`. */\nexport const DEFAULT_SHIFT_EASING = 'cubic-bezier(0.2, 0, 0, 1)';\n\n/** Default drop animation duration (ms) used when the config omits `dropDuration`. */\nexport const DEFAULT_DROP_DURATION = 200;\n\n/** Default drop animation easing used when the config omits `dropEasing`. */\nexport const DEFAULT_DROP_EASING = 'cubic-bezier(0.2, 0, 0, 1)';\n\n/**\n * Opt-in animation configuration. When provided, items displaced by the placeholder\n * slide into their new position instead of jumping, and on drop the drag preview glides\n * into the item's final position. Resolved through the element\n * injector, so it can be provided app-wide or per component subtree.\n *\n * Animations are skipped when the user prefers reduced motion. Values are read each\n * time an animation starts, so getters can toggle the animation at runtime.\n *\n * @example\n * ```typescript\n * providers: [{ provide: VDND_ANIMATION_CONFIG, useValue: { shiftDuration: 200 } }]\n * ```\n */\nexport const VDND_ANIMATION_CONFIG = new InjectionToken<VdndAnimationConfig>(\n 'VDND_ANIMATION_CONFIG',\n);\n","import { Injectable } from '@angular/core';\nimport { DragState } from '../models/drag-drop.models';\n\n/**\n * Receives the ended drag state when a drag is dropped on the droppable. Returns whether it\n * took the drop (false when it declines, e.g. because it is disabled).\n */\nexport type DropHandler = (endedState: DragState) => boolean;\n\ninterface DroppableRegistration {\n readonly element: HTMLElement;\n readonly id: string;\n readonly group: string;\n readonly onDrop: DropHandler | null;\n}\n\n/**\n * Registry of the rendered droppables, keyed by group and by ID.\n *\n * `DroppableDirective` registers its element once rendered and unregisters on destroy, so drag\n * code reads the droppables of one group instead of querying the whole document for\n * `data-droppable-*` attributes. That keeps lookups proportional to the group, not the page,\n * and finds droppables a document query cannot reach (inside shadow roots). It also delivers\n * a drop to its target the moment the drag ends (`DragStateService.endDrag`).\n * @internal\n */\n@Injectable({\n providedIn: 'root',\n})\nexport class DroppableRegistryService {\n readonly #byGroup = new Map<string, DroppableRegistration[]>();\n\n readonly #byId = new Map<string, DroppableRegistration[]>();\n\n readonly #listeners = new Set<(group: string) => void>();\n\n /**\n * Register a droppable, with the handler that receives drops on it. Returns the function\n * that unregisters it; calling that more than once is a no-op.\n */\n register(\n element: HTMLElement,\n id: string,\n group: string,\n onDrop: DropHandler | null = null,\n ): () => void {\n const registration: DroppableRegistration = { element, id, group, onDrop };\n\n this.#add(this.#byGroup, group, registration);\n if (id) {\n this.#add(this.#byId, id, registration);\n }\n this.#notify(group);\n\n let registered = true;\n return () => {\n if (!registered) {\n return;\n }\n registered = false;\n this.#remove(this.#byGroup, group, registration);\n if (id) {\n this.#remove(this.#byId, id, registration);\n }\n this.#notify(group);\n };\n }\n\n /**\n * The group's droppables that are in the document, in document order (the order they are\n * painted in, which hit-testing relies on). Returns a new array.\n *\n * Sorted on every call rather than cached: a list moved in the DOM keeps its registration.\n * Callers read it at drag start and on candidate changes, not per frame.\n */\n getGroup(group: string): HTMLElement[] {\n const registrations = this.#byGroup.get(group);\n if (!registrations) {\n return [];\n }\n\n const elements: HTMLElement[] = [];\n for (const { element } of registrations) {\n if (element.isConnected) {\n elements.push(element);\n }\n }\n return elements.sort(compareElements);\n }\n\n /**\n * The droppable with this ID that is in the document, or null. If a re-render briefly\n * leaves two with the same ID, returns the first in document order.\n */\n getById(id: string): HTMLElement | null {\n return this.#firstById(id)?.element ?? null;\n }\n\n /**\n * Hand an ended drag to the drop handler of its target (`activeDroppableId`), so a drop\n * reaches exactly one droppable. IDs should be unique; if several connected droppables share\n * it (briefly, while re-rendering), those in the source list's group come first, then\n * document order, and the first that takes the drop gets it. Does nothing when the drag had\n * no target or item, or the target is no longer registered.\n */\n deliverDrop(endedState: DragState): void {\n const targetId = endedState.activeDroppableId;\n const registrations = targetId ? this.#byId.get(targetId) : undefined;\n if (!registrations || !endedState.draggedItem) {\n return;\n }\n\n const sourceId = endedState.sourceDroppableId;\n const dragGroup = sourceId ? this.#firstById(sourceId)?.group : undefined;\n const candidates = registrations\n .filter((registration) => registration.onDrop && registration.element.isConnected)\n .sort(\n (a, b) =>\n Number(b.group === dragGroup) - Number(a.group === dragGroup) ||\n compareElements(a.element, b.element),\n );\n\n for (const { onDrop } of candidates) {\n if (onDrop?.(endedState)) {\n return;\n }\n }\n }\n\n /**\n * Call `listener` with the group whenever a droppable of that group registers or\n * unregisters. Returns the function that removes the listener.\n */\n onChange(listener: (group: string) => void): () => void {\n this.#listeners.add(listener);\n return () => this.#listeners.delete(listener);\n }\n\n /** The registration with this ID that is in the document and first in document order. */\n #firstById(id: string): DroppableRegistration | null {\n const registrations = this.#byId.get(id);\n if (!registrations) {\n return null;\n }\n\n let match: DroppableRegistration | null = null;\n for (const registration of registrations) {\n if (\n registration.element.isConnected &&\n (!match || compareElements(registration.element, match.element) < 0)\n ) {\n match = registration;\n }\n }\n return match;\n }\n\n #add(\n map: Map<string, DroppableRegistration[]>,\n key: string,\n registration: DroppableRegistration,\n ): void {\n const list = map.get(key);\n if (list) {\n list.push(registration);\n } else {\n map.set(key, [registration]);\n }\n }\n\n #remove(\n map: Map<string, DroppableRegistration[]>,\n key: string,\n registration: DroppableRegistration,\n ): void {\n const list = map.get(key);\n const index = list?.indexOf(registration) ?? -1;\n if (!list || index === -1) {\n return;\n }\n list.splice(index, 1);\n if (list.length === 0) {\n map.delete(key);\n }\n }\n\n #notify(group: string): void {\n for (const listener of this.#listeners) {\n listener(group);\n }\n }\n}\n\n/**\n * Negative when `a` comes before `b` in the document (an ancestor comes before its\n * descendants). Across shadow roots the order is stable but implementation-defined.\n */\nfunction compareElements(a: Node, b: Node): number {\n if (a === b) {\n return 0;\n }\n const position = a.compareDocumentPosition(b);\n return position & Node.DOCUMENT_POSITION_FOLLOWING ||\n position & Node.DOCUMENT_POSITION_CONTAINED_BY\n ? -1\n : 1;\n}\n","import { computed, effect, inject, Injectable, signal } from '@angular/core';\nimport { CursorPosition, DraggedItem, DragState, GrabOffset } from '../models/drag-drop.models';\nimport { DroppableRegistryService } from './droppable-registry.service';\n\n/**\n * Internal state type without high-frequency fields.\n * `cursorPosition`, `keyboardTargetIndex`, `activeDroppableId`, `placeholderId`\n * and `placeholderIndex` are split into dedicated signals so that high-frequency\n * pointer/placeholder updates don't trigger re-evaluation of rarely-changing\n * computeds (or rebuild the core state object every frame).\n */\ntype CoreDragState = Omit<\n DragState,\n | 'cursorPosition'\n | 'keyboardTargetIndex'\n | 'activeDroppableId'\n | 'placeholderId'\n | 'placeholderIndex'\n>;\n\nconst INITIAL_CORE_STATE: CoreDragState = {\n isDragging: false,\n draggedItem: null,\n sourceDroppableId: null,\n sourceIndex: null,\n grabOffset: null,\n initialPosition: null,\n lockAxis: null,\n isKeyboardDrag: false,\n};\n\n/**\n * Central service for managing drag-and-drop state.\n * Uses signals for reactive state management.\n *\n * Architecture: High-frequency fields (`cursorPosition`, `keyboardTargetIndex`,\n * `activeDroppableId`, `placeholderId`, `placeholderIndex`) are stored in dedicated\n * signals, separate from the core state. This prevents 60fps cursor and\n * placeholder updates from rebuilding the core state object or re-evaluating the\n * 8+ computeds that only depend on rarely-changing properties (isDragging,\n * draggedItem, etc.).\n */\n@Injectable({\n providedIn: 'root',\n})\nexport class DragStateService {\n readonly #droppableRegistry = inject(DroppableRegistryService);\n\n /** Core state signal — contains all rarely-changing properties */\n readonly #state = signal<CoreDragState>(INITIAL_CORE_STATE);\n\n /** High-frequency cursor position — updated at 60fps during pointer drag */\n readonly #cursorPosition = signal<CursorPosition | null>(null);\n\n /** High-frequency keyboard target index — updated on each arrow key press */\n readonly #keyboardTargetIndex = signal<number | null>(null);\n\n /** ID of the droppable currently being hovered over — changes on droppable crossings */\n readonly #activeDroppableId = signal<string | null>(null);\n\n /** `END_OF_LIST` while a droppable is targeted, otherwise null; see placeholderIndex */\n readonly #placeholderId = signal<string | null>(null);\n\n /** Index where the placeholder should be inserted — updated on each placeholder move */\n readonly #placeholderIndex = signal<number | null>(null);\n\n /** Snapshot captured synchronously immediately before the last drag state reset. */\n readonly #endedDragState = signal<DragState | null>(null);\n\n /** Flag indicating if the last drag was cancelled (not dropped) */\n readonly #wasCancelled = signal<boolean>(false);\n\n /** Whether the last drag was cancelled (a cancelled drag delivers no drop) */\n readonly wasCancelled = this.#wasCancelled.asReadonly();\n\n /** Snapshot captured synchronously before the last drag reset. */\n readonly endedDragState = this.#endedDragState.asReadonly();\n\n /** Whether a drag operation is in progress */\n readonly isDragging = computed(() => this.#state().isDragging);\n\n /** The currently dragged item, or null */\n readonly draggedItem = computed(() => this.#state().draggedItem);\n\n /** ID of the currently dragged item, or null (convenience signal for filtering) */\n readonly draggedItemId = computed(() => this.#state().draggedItem?.draggableId ?? null);\n\n /** ID of the droppable where the drag started */\n readonly sourceDroppableId = computed(() => this.#state().sourceDroppableId);\n\n /** Original index of the dragged item in the source list */\n readonly sourceIndex = computed(() => this.#state().sourceIndex);\n\n /** ID of the droppable currently being hovered over */\n readonly activeDroppableId = this.#activeDroppableId.asReadonly();\n\n /**\n * `END_OF_LIST` while a droppable is targeted, otherwise null.\n * @deprecated It never identifies an item. Use `placeholderIndex`. Will be removed in the next\n * major version.\n */\n readonly placeholderId = this.#placeholderId.asReadonly();\n\n /** Index where the placeholder should be inserted */\n readonly placeholderIndex = this.#placeholderIndex.asReadonly();\n\n /** Current cursor position */\n readonly cursorPosition = this.#cursorPosition.asReadonly();\n\n /** Offset from cursor to element top-left (for maintaining grab position) */\n readonly grabOffset = computed(() => this.#state().grabOffset);\n\n /** Position when drag started (for axis locking) */\n readonly initialPosition = computed(() => this.#state().initialPosition);\n\n /** Axis to lock movement to */\n readonly lockAxis = computed(() => this.#state().lockAxis);\n\n /** Whether this is a keyboard-initiated drag */\n readonly isKeyboardDrag = computed(() => this.#state().isKeyboardDrag);\n\n /** Target index during keyboard navigation */\n readonly keyboardTargetIndex = this.#keyboardTargetIndex.asReadonly();\n\n constructor() {\n // Inject cursor styles once (for consistent grabbing cursor during drag)\n if (typeof document !== 'undefined') {\n const styleId = 'vdnd-cursor-styles';\n if (!document.getElementById(styleId)) {\n const style = document.createElement('style');\n style.id = styleId;\n style.textContent = `\n body.vdnd-dragging,\n body.vdnd-dragging * {\n cursor: grabbing !important;\n }\n `;\n document.head.appendChild(style);\n }\n }\n\n // Effect to toggle body class during drag\n effect(() => {\n if (typeof document === 'undefined') return;\n const isDragging = this.isDragging();\n document.body.classList.toggle('vdnd-dragging', isDragging);\n });\n }\n\n /**\n * Start a drag operation.\n * `placeholderId` is deprecated with the `placeholderId` signal; the library passes `END_OF_LIST`.\n */\n startDrag(\n item: DraggedItem,\n cursorPosition?: CursorPosition,\n grabOffset?: GrabOffset,\n lockAxis?: 'x' | 'y' | null,\n activeDroppableId?: string | null,\n placeholderId?: string | null,\n placeholderIndex?: number | null,\n sourceIndex?: number | null,\n isKeyboardDrag?: boolean,\n axisLockPosition?: CursorPosition,\n ): void {\n // Reset terminal drag metadata at start of new drag\n this.#endedDragState.set(null);\n this.#wasCancelled.set(false);\n this.#cursorPosition.set(cursorPosition ?? null);\n this.#keyboardTargetIndex.set(isKeyboardDrag ? (sourceIndex ?? 0) : null);\n this.#activeDroppableId.set(activeDroppableId ?? null);\n this.#placeholderId.set(placeholderId ?? null);\n this.#placeholderIndex.set(placeholderIndex ?? null);\n this.#state.set({\n isDragging: true,\n draggedItem: item,\n sourceDroppableId: item.droppableId,\n sourceIndex: sourceIndex ?? null,\n grabOffset: grabOffset ?? null,\n initialPosition: axisLockPosition ?? cursorPosition ?? null,\n lockAxis: lockAxis ?? null,\n isKeyboardDrag: isKeyboardDrag ?? false,\n });\n }\n\n /**\n * Update the drag position and targets.\n * `placeholderId` is deprecated with the `placeholderId` signal; the library passes `END_OF_LIST`.\n */\n updateDragPosition(update: {\n cursorPosition: CursorPosition;\n activeDroppableId: string | null;\n placeholderId: string | null;\n placeholderIndex: number | null;\n }): void {\n if (!this.#state().isDragging) {\n return;\n }\n\n // Write cursor to dedicated high-frequency signal\n this.#cursorPosition.set(update.cursorPosition);\n\n // Each target lives in its own signal, so a placeholder-only frame never\n // rebuilds the core state object or re-fires the rarely-changing computeds.\n // Signals already no-op on identical values, so unconditional sets are safe.\n this.#activeDroppableId.set(update.activeDroppableId);\n this.#placeholderId.set(update.placeholderId);\n this.#placeholderIndex.set(update.placeholderIndex);\n }\n\n /**\n * Update just the active droppable.\n */\n setActiveDroppable(droppableId: string | null): void {\n if (!this.#state().isDragging) {\n return;\n }\n\n this.#activeDroppableId.set(droppableId);\n }\n\n /**\n * Update just the placeholder ID.\n * @deprecated Sets only the deprecated `placeholderId`. Will be removed in the next major\n * version.\n */\n setPlaceholder(placeholderId: string | null): void {\n if (!this.#state().isDragging) {\n return;\n }\n\n this.#placeholderId.set(placeholderId);\n }\n\n /**\n * Update only the placeholder signals without touching cursor position or active droppable.\n *\n * Used by the autoscroll scroll-only fast path: when a scroll fires, the cursor has not\n * moved, so only the placeholder index needs recalculation. Skipping the cursor and\n * active-droppable writes avoids spurious re-evaluation of computeds that read those signals.\n * `placeholderId` is deprecated with the `placeholderId` signal; the library passes `END_OF_LIST`.\n */\n updateScrollOnlyPlaceholder(placeholderId: string | null, placeholderIndex: number | null): void {\n if (!this.#state().isDragging) {\n return;\n }\n\n this.#placeholderId.set(placeholderId);\n this.#placeholderIndex.set(placeholderIndex);\n }\n\n /**\n * End the drag operation and reset state (normal drop), then deliver the drop: the target\n * droppable (`activeDroppableId`) emits `drop` before this returns.\n */\n endDrag(): void {\n // Only a drag in progress ends. Again (e.g. from a drop handler) it would overwrite the\n // ended drag, which the drop animation reads, with an empty one.\n if (!this.#state().isDragging) {\n return;\n }\n\n const endedState = this.getStateSnapshot();\n this.#endedDragState.set(endedState);\n this.#wasCancelled.set(false);\n this.#resetHighFrequencySignals();\n this.#state.set(INITIAL_CORE_STATE);\n\n // After the reset, so the drop handler sees the drag as over. Delivered here rather than\n // from a droppable effect on the next change detection: by then the target may already\n // be destroyed or re-created (a drop zone rendered only while dragging, a list replaced\n // by a (dragEnd) handler), and every other droppable would have to tell a new drop from\n // an old one.\n this.#droppableRegistry.deliverDrop(endedState);\n }\n\n /**\n * Cancel the drag operation (escape key, disabled, etc.).\n */\n cancelDrag(): void {\n if (!this.#state().isDragging) {\n return;\n }\n\n this.#endedDragState.set(this.getStateSnapshot());\n this.#wasCancelled.set(true);\n this.#resetHighFrequencySignals();\n this.#state.set(INITIAL_CORE_STATE);\n }\n\n /**\n * Reset the dedicated high-frequency signals to their initial null state.\n */\n #resetHighFrequencySignals(): void {\n this.#cursorPosition.set(null);\n this.#keyboardTargetIndex.set(null);\n this.#activeDroppableId.set(null);\n this.#placeholderId.set(null);\n this.#placeholderIndex.set(null);\n }\n\n /**\n * Check if a specific droppable is currently active.\n */\n isDroppableActive(droppableId: string): boolean {\n return this.#activeDroppableId() === droppableId;\n }\n\n /**\n * Get the current state snapshot (for event creation).\n */\n getStateSnapshot(): DragState {\n return {\n ...this.#state(),\n activeDroppableId: this.#activeDroppableId(),\n placeholderId: this.#placeholderId(),\n placeholderIndex: this.#placeholderIndex(),\n cursorPosition: this.#cursorPosition(),\n keyboardTargetIndex: this.#keyboardTargetIndex(),\n };\n }\n\n /**\n * Update the keyboard target index (for keyboard drag navigation).\n * Also updates placeholder position to match, applying same-list adjustment.\n */\n setKeyboardTargetIndex(targetIndex: number): void {\n if (!this.#state().isDragging || !this.#state().isKeyboardDrag) {\n return;\n }\n\n const state = this.#state();\n // Same-list adjustment: if target is at or after source, add 1\n // This accounts for the hidden item shifting everything up visually\n const sourceDroppableId = state.draggedItem?.droppableId;\n const activeDroppableId = this.#activeDroppableId();\n const isSameList = sourceDroppableId === activeDroppableId;\n const sourceIndex = state.sourceIndex ?? -1;\n\n let placeholderIndex = targetIndex;\n if (isSameList && sourceIndex >= 0 && targetIndex >= sourceIndex) {\n placeholderIndex = targetIndex + 1;\n }\n\n this.#keyboardTargetIndex.set(targetIndex);\n this.#placeholderIndex.set(placeholderIndex);\n }\n\n /**\n * Update the active droppable during keyboard navigation (for cross-list moves).\n */\n setKeyboardActiveDroppable(droppableId: string | null, targetIndex: number): void {\n if (!this.#state().isDragging || !this.#state().isKeyboardDrag) {\n return;\n }\n\n const state = this.#state();\n // Same-list adjustment: if moving back to source list and target is at or after source, add 1\n const sourceDroppableId = state.draggedItem?.droppableId;\n const isSameList = sourceDroppableId === droppableId;\n const sourceIndex = state.sourceIndex ?? -1;\n\n let placeholderIndex = targetIndex;\n if (isSameList && sourceIndex >= 0 && targetIndex >= sourceIndex) {\n placeholderIndex = targetIndex + 1;\n }\n\n this.#keyboardTargetIndex.set(targetIndex);\n this.#activeDroppableId.set(droppableId);\n this.#placeholderIndex.set(placeholderIndex);\n }\n}\n","import { DestroyRef, inject, Injectable, NgZone } from '@angular/core';\nimport { DroppableRegistryService } from './droppable-registry.service';\n\n/**\n * Snapshot of the candidate droppables for an active drag session.\n * Rects are cached so per-pointermove hit-testing is pure geometry, avoiding the\n * forced layout flush that `document.elementFromPoint` (plus the pointer-events\n * style write it required) imposed on the hottest drag loop.\n */\ninterface DragSessionSnapshot {\n groupName: string;\n /** Candidate droppables in document order (document order === default paint order). */\n candidates: HTMLElement[];\n /** Cached bounding rects, parallel to `candidates`. */\n rects: DOMRect[];\n /** When true, rects are re-read on the next hit-test (set on scroll/resize). */\n dirty: boolean;\n /**\n * When true, the candidate *list* (not just its rects) is re-queried on the next\n * hit-test. Set when a droppable is added/removed mid-drag so a newly mounted\n * target becomes hit-testable and a removed one stops lingering.\n */\n candidatesStale: boolean;\n /** Bound scroll/resize listener used to mark rects dirty. */\n onViewportChange: () => void;\n /**\n * ResizeObserver watching the candidate droppables so a container-only layout\n * change (which fires no window scroll/resize) still invalidates cached rects.\n * Null when `ResizeObserver` is unavailable (e.g. SSR / jsdom).\n */\n resizeObserver: ResizeObserver | null;\n}\n\n/** The parent lookups stop below `<body>`: it and `<html>` never count as list or item. */\nfunction isPageRoot(element: Element): boolean {\n return element.tagName === 'BODY' || element.tagName === 'HTML';\n}\n\n/**\n * Service for calculating drop positions and finding elements at cursor positions.\n * This is the core algorithm that makes virtual scroll + drag-and-drop work together.\n */\n@Injectable({\n providedIn: 'root',\n})\nexport class PositionCalculatorService {\n readonly #ngZone = inject(NgZone);\n readonly #registry = inject(DroppableRegistryService);\n\n /** Data attribute used to identify droppable elements */\n readonly #DROPPABLE_ID_ATTR = 'data-droppable-id';\n\n /** Data attribute used to identify droppable groups */\n readonly #DROPPABLE_GROUP_ATTR = 'data-droppable-group';\n\n /** Data attribute reflecting a droppable's disabled state (present === disabled) */\n readonly #DROPPABLE_DISABLED_ATTR = 'data-droppable-disabled';\n\n /** Data attribute used to identify draggable elements */\n readonly #DRAGGABLE_ID_ATTR = 'data-draggable-id';\n\n /** Reusable result object for getNearEdge (avoids per-frame allocation) */\n readonly #nearEdgeResult = { top: false, bottom: false, left: false, right: false };\n\n /** Active drag session rect snapshot, or null when no drag is in progress. */\n #session: DragSessionSnapshot | null = null;\n\n constructor() {\n // A droppable (un)registering mid-drag makes the next hit-test re-read the candidates.\n // Removed on destroy in case the service is provided below root.\n const removeListener = this.#registry.onChange((group) => this.notifyCandidatesChanged(group));\n inject(DestroyRef).onDestroy(() => {\n removeListener();\n this.endDragSession();\n });\n }\n\n /**\n * Begin a drag session: snapshot the candidate droppables for `groupName` and\n * their rects once, then watch for viewport changes (scroll/resize) that would\n * invalidate those rects. While a session is active, `findDroppableAtPoint`\n * runs as pure geometry against the cached rects instead of `elementFromPoint`.\n *\n * Safe to call repeatedly — a new call replaces any previous session.\n */\n beginDragSession(groupName: string): void {\n this.endDragSession();\n\n const candidates = this.#queryDroppables(groupName);\n const onViewportChange = () => {\n if (this.#session) {\n this.#session.dirty = true;\n }\n };\n\n this.#session = {\n groupName,\n candidates,\n rects: this.#measureRects(candidates, []),\n dirty: false,\n candidatesStale: false,\n onViewportChange,\n resizeObserver: this.#createResizeObserver(),\n };\n\n // A container-only reflow (an element resize that fires no window scroll/resize)\n // would otherwise leave stale rects — observe the candidates so it marks them dirty.\n this.#observeCandidates(this.#session);\n\n // Capture-phase scroll catches scrolling on any ancestor scroller (scroll does\n // not bubble); resize covers viewport changes. Both only mark rects dirty —\n // the actual re-read is deferred to the next hit-test.\n if (typeof window !== 'undefined') {\n this.#ngZone.runOutsideAngular(() => {\n window.addEventListener('scroll', onViewportChange, { capture: true, passive: true });\n window.addEventListener('resize', onViewportChange, { passive: true });\n });\n }\n }\n\n /**\n * End the current drag session and detach viewport listeners.\n * Safe to call when no session is active.\n */\n endDragSession(): void {\n const session = this.#session;\n if (!session) {\n return;\n }\n this.#session = null;\n session.resizeObserver?.disconnect();\n if (typeof window !== 'undefined') {\n window.removeEventListener('scroll', session.onViewportChange, { capture: true });\n window.removeEventListener('resize', session.onViewportChange);\n }\n }\n\n /**\n * Mark the cached droppable rects as stale so they are re-read on the next\n * hit-test. Called explicitly from the autoscroll recalculation path, where the\n * scroll event has not yet fired but the container has already moved.\n */\n invalidateDroppableRects(): void {\n if (this.#session) {\n this.#session.dirty = true;\n }\n }\n\n /**\n * Re-read the candidate droppable *list* for the active session from the registry and\n * re-read their rects. Unlike {@link invalidateDroppableRects} (which only refreshes\n * rects), this picks up droppables added or removed since the snapshot was captured at\n * drag start. Registration changes already trigger it on the next hit-test; this is the\n * manual escape hatch.\n *\n * Safe to call when no session is active (no-op).\n */\n refreshCandidates(): void {\n const session = this.#session;\n if (!session) {\n return;\n }\n session.candidates = this.#queryDroppables(session.groupName);\n session.rects = this.#measureRects(session.candidates, []);\n session.dirty = false;\n session.candidatesStale = false;\n this.#observeCandidates(session);\n }\n\n /**\n * Signal that the set of droppables for `groupName` may have changed (a droppable\n * registered or unregistered mid-drag). Defers the re-read to the next hit-test, keeping\n * this notification path cheap.\n *\n * Called for every droppable registry change. No-op when the active session belongs to\n * a different group or no session is active.\n */\n notifyCandidatesChanged(groupName: string): void {\n if (this.#session && this.#session.groupName === groupName) {\n this.#session.candidatesStale = true;\n }\n }\n\n /**\n * Find the droppable element at a given point.\n *\n * Uses pure geometric hit-testing against snapshotted droppable rects. When a\n * drag session is active (see {@link beginDragSession}) the rects are cached and\n * reused across frames; otherwise a one-shot DOM query is performed. The\n * `draggedElement` parameter is retained for API compatibility but no longer\n * needs to be hidden — geometry does not depend on cursor occlusion.\n *\n * @param x - Cursor X coordinate\n * @param y - Cursor Y coordinate\n * @param _draggedElement - The element being dragged (unused; kept for compatibility)\n * @param groupName - The drag-and-drop group name to filter by\n * @returns The droppable element, or null if none found\n */\n findDroppableAtPoint(\n x: number,\n y: number,\n _draggedElement: HTMLElement,\n groupName: string,\n ): HTMLElement | null {\n const session = this.#session;\n if (session && session.groupName === groupName) {\n if (session.candidatesStale) {\n // A droppable was added/removed mid-drag: re-query the list (also refreshes rects).\n this.refreshCandidates();\n } else if (session.dirty) {\n this.#measureRects(session.candidates, session.rects);\n session.dirty = false;\n }\n return this.#hitTest(x, y, session.candidates, session.rects);\n }\n\n // No active session: one-shot geometric query (still avoids elementFromPoint).\n const candidates = this.#queryDroppables(groupName);\n return this.#hitTest(x, y, candidates, this.#measureRects(candidates, []));\n }\n\n /**\n * Look up a droppable element by its ID.\n *\n * When a drag session is active, searches the cached candidate list. Otherwise looks the\n * ID up in the droppable registry. Neither queries the document.\n *\n * Intended for the autoscroll scroll-only fast path, where the active droppable is already\n * known and only the placeholder index needs recalculation.\n */\n getDroppableById(id: string): HTMLElement | null {\n if (this.#session) {\n for (const candidate of this.#session.candidates) {\n if (candidate.getAttribute(this.#DROPPABLE_ID_ATTR) === id) {\n return candidate;\n }\n }\n return null;\n }\n\n return this.#registry.getById(id);\n }\n\n /**\n * All rendered droppables belonging to a group, in document order, from the registry.\n *\n * All group members are included — the disabled check happens per-frame in\n * {@link #hitTest} rather than here, because a droppable can be disabled or\n * re-enabled mid-drag (e.g. a consumer disabling incompatible targets from a\n * `(dragStart)` handler, which fires AFTER the candidate snapshot is captured).\n */\n #queryDroppables(groupName: string): HTMLElement[] {\n return this.#registry.getGroup(groupName);\n }\n\n /**\n * The ancestor that clips a candidate's hit-test rect: its nearest `.vdnd-scrollable`\n * ancestor, or null when it has none or is one itself. Without clipping a droppable scrolled\n * mostly out of a clipping container still hit-tests over its full unclipped rect (issue #23\n * case 3).\n */\n #clipOf(el: HTMLElement): Element | null {\n const scrollable = el.closest('.vdnd-scrollable');\n return scrollable === el ? null : scrollable;\n }\n\n /**\n * Measure the candidates' hit-test rects into `rects`, each clipped to its clip ancestor (see\n * `#clipOf`). Consecutive candidates in one scroller (lists side by side in it) read its rect\n * once. The ancestor is looked up on each pass: a list moved to another scroller mid-drag keeps\n * its registration. The intersection is built as a plain DOMRect; an empty intersection yields\n * a negative width/height so the `#hitTest` bounds check can never match it.\n */\n #measureRects(candidates: readonly HTMLElement[], rects: DOMRect[]): DOMRect[] {\n let lastClip: Element | null = null;\n let lastClipRect: DOMRect | null = null;\n for (let i = 0; i < candidates.length; i++) {\n const rect = candidates[i].getBoundingClientRect();\n const clip = this.#clipOf(candidates[i]);\n if (!clip) {\n rects[i] = rect;\n continue;\n }\n if (clip !== lastClip || !lastClipRect) {\n lastClip = clip;\n lastClipRect = clip.getBoundingClientRect();\n }\n const top = Math.max(rect.top, lastClipRect.top);\n const left = Math.max(rect.left, lastClipRect.left);\n const right = Math.min(rect.right, lastClipRect.right);\n const bottom = Math.min(rect.bottom, lastClipRect.bottom);\n rects[i] = new DOMRect(left, top, right - left, bottom - top);\n }\n return rects;\n }\n\n /**\n * Create a ResizeObserver (run outside Angular per CLAUDE.md) that marks the session's\n * cached rects dirty when a candidate resizes. Returns null when ResizeObserver is\n * unavailable (SSR / jsdom) so callers degrade gracefully.\n */\n #createResizeObserver(): ResizeObserver | null {\n if (typeof ResizeObserver === 'undefined') {\n return null;\n }\n return this.#ngZone.runOutsideAngular(\n () =>\n new ResizeObserver(() => {\n if (this.#session) {\n this.#session.dirty = true;\n }\n }),\n );\n }\n\n /**\n * Point the session's ResizeObserver at the current candidate list, dropping any\n * previously observed elements. Called on session start and whenever the candidate\n * list is refreshed.\n */\n #observeCandidates(session: DragSessionSnapshot): void {\n const observer = session.resizeObserver;\n if (!observer) {\n return;\n }\n this.#ngZone.runOutsideAngular(() => {\n observer.disconnect();\n for (const candidate of session.candidates) {\n observer.observe(candidate);\n }\n });\n }\n\n /**\n * Whether a droppable element is currently disabled (reflected via the\n * `data-droppable-disabled` attribute by `DroppableDirective`). Read live on each\n * hit-test / navigation step so disabled↔enabled transitions during an active drag\n * take effect immediately. Disabled droppables are excluded from all drag-time\n * candidate sets — pointer hit-testing and keyboard cross-list navigation.\n */\n #isDroppableDisabled(el: HTMLElement): boolean {\n return el.hasAttribute(this.#DROPPABLE_DISABLED_ATTR);\n }\n\n /**\n * Geometric hit-test: return the last candidate (in document order) whose rect\n * contains the point. \"Last in document order\" reproduces the painter's-order\n * tie-break that `elementFromPoint` provided for free — a nested or later\n * overlapping droppable is painted on top of an earlier/ancestor one.\n *\n * Currently-disabled candidates are skipped here (not filtered from the snapshot) so\n * that toggling `disabled` mid-drag takes effect on the very next frame. The check is\n * a cheap `hasAttribute` read that does not force layout, keeping the loop hot.\n */\n #hitTest(x: number, y: number, candidates: HTMLElement[], rects: DOMRect[]): HTMLElement | null {\n let match: HTMLElement | null = null;\n for (let i = 0; i < candidates.length; i++) {\n const candidate = candidates[i];\n if (this.#isDroppableDisabled(candidate)) {\n continue;\n }\n const r = rects[i];\n if (x >= r.left && x <= r.right && y >= r.top && y <= r.bottom) {\n match = candidate;\n }\n }\n return match;\n }\n\n /**\n * Find the draggable element at a given point.\n *\n * @param x - Cursor X coordinate\n * @param y - Cursor Y coordinate\n * @param draggedElement - The element being dragged (will be temporarily hidden)\n * @returns The draggable element, or null if none found\n */\n findDraggableAtPoint(x: number, y: number, draggedElement: HTMLElement): HTMLElement | null {\n const isHidden = draggedElement.offsetParent === null;\n\n let originalPointerEvents: string | undefined;\n if (!isHidden) {\n originalPointerEvents = draggedElement.style.pointerEvents;\n draggedElement.style.pointerEvents = 'none';\n }\n\n try {\n const elementAtPoint = document.elementFromPoint(x, y);\n if (!elementAtPoint) {\n return null;\n }\n\n return this.getDraggableParent(elementAtPoint as HTMLElement);\n } finally {\n if (!isHidden) {\n draggedElement.style.pointerEvents = originalPointerEvents!;\n }\n }\n }\n\n /**\n * Walk up the DOM tree to find a droppable parent element.\n *\n * @param element - Starting element\n * @param groupName - The drag-and-drop group name to filter by\n * @returns The droppable parent element, or null if none found\n */\n getDroppableParent(element: HTMLElement, groupName: string): HTMLElement | null {\n // An empty group name never matches (an empty attribute value is no group)\n if (!groupName) {\n return null;\n }\n\n // Match on the attribute's presence and compare the value here, so the group name needs no\n // selector escaping. Nearer droppables of other groups are skipped.\n const selector = `[${this.#DROPPABLE_GROUP_ATTR}]`;\n let current = element.closest<HTMLElement>(selector);\n while (current && !isPageRoot(current)) {\n if (current.getAttribute(this.#DROPPABLE_GROUP_ATTR) === groupName) {\n return current;\n }\n current = current.parentElement?.closest<HTMLElement>(selector) ?? null;\n }\n\n return null;\n }\n\n /**\n * Walk up the DOM tree to find a draggable parent element.\n *\n * @param element - Starting element\n * @returns The draggable parent element, or null if none found\n */\n getDraggableParent(element: HTMLElement): HTMLElement | null {\n const selector = `[${this.#DRAGGABLE_ID_ATTR}]:not([${this.#DRAGGABLE_ID_ATTR}=\"\"])`;\n const draggable = element.closest<HTMLElement>(selector);\n return draggable && !isPageRoot(draggable) ? draggable : null;\n }\n\n /**\n * Get the draggable ID from an element.\n */\n getDraggableId(element: HTMLElement): string | null {\n return element.getAttribute(this.#DRAGGABLE_ID_ATTR);\n }\n\n /**\n * Get the droppable ID from an element.\n */\n getDroppableId(element: HTMLElement): string | null {\n return element.getAttribute(this.#DROPPABLE_ID_ATTR);\n }\n\n /**\n * Calculate the drop index based on mathematical position.\n *\n * This is an alternative approach that doesn't require the target element\n * to be in the DOM. Useful when the target might be virtualized away.\n *\n * @param scrollTop - Current scroll position of the container\n * @param cursorY - Cursor Y position (viewport-relative)\n * @param containerTop - Top position of the container (viewport-relative)\n * @param itemHeight - Height of each item\n * @param totalItems - Total number of items in the list\n * @returns The calculated drop index\n */\n calculateDropIndex(\n scrollTop: number,\n cursorY: number,\n containerTop: number,\n itemHeight: number,\n totalItems: number,\n ): number {\n // Calculate the position relative to the container's content\n const relativeY = cursorY - containerTop + scrollTop;\n\n // Calculate which item index this corresponds to\n const index = Math.floor(relativeY / itemHeight);\n\n // Clamp to valid range\n return Math.max(0, Math.min(index, totalItems));\n }\n\n /**\n * Check if a point is within a specific threshold of a container's edge.\n *\n * @param position - Current cursor position\n * @param containerRect - Container's bounding rect\n * @param threshold - Distance from edge to trigger (in pixels)\n * @returns Object indicating which edges are near\n */\n getNearEdge(\n position: { x: number; y: number },\n containerRect: DOMRect,\n threshold: number,\n ): { top: boolean; bottom: boolean; left: boolean; right: boolean } {\n this.#nearEdgeResult.top = position.y - containerRect.top <= threshold;\n this.#nearEdgeResult.bottom = containerRect.bottom - position.y <= threshold;\n this.#nearEdgeResult.left = position.x - containerRect.left <= threshold;\n this.#nearEdgeResult.right = containerRect.right - position.x <= threshold;\n return this.#nearEdgeResult;\n }\n\n /**\n * Determine if the cursor is inside a container.\n */\n isInsideContainer(position: { x: number; y: number }, containerRect: DOMRect): boolean {\n return (\n position.x >= containerRect.left &&\n position.x <= containerRect.right &&\n position.y >= containerRect.top &&\n position.y <= containerRect.bottom\n );\n }\n\n /**\n * Find an adjacent droppable in the specified direction (left or right).\n * Used for cross-list keyboard navigation.\n *\n * @param currentDroppableId - The ID of the current droppable\n * @param direction - 'left' or 'right'\n * @param groupName - The drag-and-drop group name\n * @returns Object with droppable info, or null if none found\n */\n findAdjacentDroppable(\n currentDroppableId: string,\n direction: 'left' | 'right',\n groupName: string,\n ): { element: HTMLElement; id: string } | null {\n // Include disabled droppables when establishing left-to-right order and locating the\n // current container — otherwise a container disabled mid-drag (its own index becomes\n // -1) would trap the drag with no reachable neighbour. Disabled droppables are skipped\n // as *targets* during the outward scan below instead.\n const allDroppables = this.#registry.getGroup(groupName);\n\n if (allDroppables.length <= 1) {\n return null;\n }\n\n // Get bounding rects, IDs, and disabled state, sorted by X position\n const droppableInfos: { element: HTMLElement; id: string; rect: DOMRect; disabled: boolean }[] =\n [];\n\n allDroppables.forEach((el) => {\n const id = el.getAttribute(this.#DROPPABLE_ID_ATTR);\n if (id) {\n droppableInfos.push({\n element: el,\n id,\n rect: el.getBoundingClientRect(),\n disabled: this.#isDroppableDisabled(el),\n });\n }\n });\n\n // Sort by X position (left to right)\n droppableInfos.sort((a, b) => a.rect.left - b.rect.left);\n\n // Find current droppable index (among all, including a now-disabled current container)\n const currentIndex = droppableInfos.findIndex((d) => d.id === currentDroppableId);\n if (currentIndex === -1) {\n return null;\n }\n\n // Scan outward in the requested direction, skipping disabled droppables, until the\n // first enabled neighbour (or run off the end of the list).\n const step = direction === 'left' ? -1 : 1;\n for (let i = currentIndex + step; i >= 0 && i < droppableInfos.length; i += step) {\n const target = droppableInfos[i];\n if (target.disabled) {\n continue;\n }\n return {\n element: target.element,\n id: target.id,\n };\n }\n\n return null;\n }\n\n /**\n * Whether the droppable with the given ID is currently disabled. A droppable that cannot\n * be found is reported as disabled (treat missing as not a valid target). Used to\n * revalidate a keyboard drag's active target at drop time, since it may have been disabled\n * after the drag navigated into it.\n */\n isDroppableDisabledById(id: string): boolean {\n const element = this.getDroppableById(id);\n return element === null || this.#isDroppableDisabled(element);\n }\n}\n","import { inject, Injectable, NgZone } from '@angular/core';\nimport { CursorPosition } from '../models/drag-drop.models';\n\n/**\n * Callback invoked each RAF frame with the latest cursor and a dirty flag.\n *\n * @param cursor — Latest cursor position queued via `queueCursorUpdate()`, or null if none.\n * @param cursorDirty — True when cursor was updated since the previous frame.\n */\nexport type SchedulerTickFn = (cursor: CursorPosition | null, cursorDirty: boolean) => void;\n\n/**\n * Single RAF loop that coordinates all drag-frame work in ordered phases:\n *\n * 1. Participant phase (READ+WRITE): registered participants run first.\n * AutoScrollService registers here to perform edge-scroll + immediate\n * placeholder recalculation in the same synchronous frame — preserving\n * the Safari synchronous-callback constraint.\n * 2. Main compute phase (COMPUTE+WRITE): onTick is called every frame with the\n * latest cursor and a `cursorDirty` flag. Callers skip their hit-test when\n * the flag is false, so autoscroll-only frames (cursor stationary) incur\n * zero hit-test work.\n * 3. Frame writer phase (WRITE): registered writers apply the state computed this\n * frame to the DOM. DragPreviewComponent writes the preview transform here, so\n * the preview moves in the frame that processed the pointer instead of waiting\n * for a change detection tick, which Angular schedules after this frame.\n *\n * PointerDragHandler calls `queueCursorUpdate()` instead of managing its own\n * RAF per pointermove. This coalesces all moves within a frame into one update\n * and ensures pointer-move work always runs after participant work.\n */\n@Injectable({\n providedIn: 'root',\n})\nexport class DragSchedulerService {\n readonly #ngZone = inject(NgZone);\n\n #rafId: number | null = null;\n #onTick: SchedulerTickFn | null = null;\n\n /** Latest cursor queued from pointer move events. */\n #pendingCursor: CursorPosition | null = null;\n /** True when a new cursor was queued since the last frame. */\n #cursorDirty = false;\n\n /** Tick participants called before the main compute phase each frame. */\n readonly #participants: (() => void)[] = [];\n\n /** Frame writers called after the main compute phase each frame. */\n readonly #frameWriters: (() => void)[] = [];\n\n /**\n * Start the scheduler RAF loop.\n * No-op if already running.\n */\n start(onTick: SchedulerTickFn): void {\n if (this.#rafId !== null) {\n return;\n }\n this.#onTick = onTick;\n this.#ngZone.runOutsideAngular(() => {\n this.#scheduleNextTick();\n });\n }\n\n /**\n * Stop the scheduler and cancel the pending RAF.\n * Safe to call when not running.\n */\n stop(): void {\n if (this.#rafId !== null) {\n cancelAnimationFrame(this.#rafId);\n this.#rafId = null;\n }\n // Null out onTick so that any in-flight RAF callback (race between cancel\n // and the browser delivering the frame) is a no-op.\n this.#onTick = null;\n this.#pendingCursor = null;\n this.#cursorDirty = false;\n }\n\n /**\n * Queue a cursor update from a pointer move event.\n * Multiple calls between frames are coalesced — only the latest matters.\n */\n queueCursorUpdate(position: CursorPosition): void {\n this.#pendingCursor = position;\n this.#cursorDirty = true;\n }\n\n /**\n * Register a function to be called at the start of each frame, before the main tick.\n * AutoScrollService registers here to perform edge-scroll within the same frame.\n * No-op if the same function reference is already registered.\n */\n addParticipant(fn: () => void): void {\n if (!this.#participants.includes(fn)) {\n this.#participants.push(fn);\n }\n }\n\n /**\n * Unregister a previously added participant.\n * No-op if the function was not registered.\n */\n removeParticipant(fn: () => void): void {\n const idx = this.#participants.indexOf(fn);\n if (idx !== -1) {\n this.#participants.splice(idx, 1);\n }\n }\n\n /**\n * Register a function to be called at the end of each frame, after the main tick.\n * DragPreviewComponent registers here to move the preview within the same frame.\n * No-op if the same function reference is already registered.\n */\n addFrameWriter(fn: () => void): void {\n if (!this.#frameWriters.includes(fn)) {\n this.#frameWriters.push(fn);\n }\n }\n\n /**\n * Unregister a previously added frame writer.\n * No-op if the function was not registered.\n */\n removeFrameWriter(fn: () => void): void {\n const idx = this.#frameWriters.indexOf(fn);\n if (idx !== -1) {\n this.#frameWriters.splice(idx, 1);\n }\n }\n\n #scheduleNextTick(): void {\n this.#rafId = requestAnimationFrame(() => this.#tick());\n }\n\n #tick(): void {\n this.#rafId = null;\n\n // Guard against the race where stop() was called but the browser already\n // queued the callback before cancelAnimationFrame() could prevent delivery.\n if (!this.#onTick) {\n return;\n }\n\n // Snapshot and reset dirty flag before participants run so that any cursor\n // update they trigger (theoretically possible in future extensions) is\n // picked up in the NEXT frame, not folded into this one's compute phase.\n const cursorDirty = this.#cursorDirty;\n this.#cursorDirty = false;\n\n // Phase 1 — participants (autoscroll scroll + synchronous placeholder update)\n for (const participant of this.#participants) {\n participant();\n }\n\n // A participant can end the drag (the autoscroll callback may cancel it), which stops\n // the scheduler and clears onTick.\n const onTick = this.#onTick;\n if (!onTick) {\n return;\n }\n\n // Phase 2 — main compute (cursor-based hit-test + signal write)\n onTick(this.#pendingCursor, cursorDirty);\n\n // stop() may have been called by onTick (the drag ended): nothing left to write.\n if (this.#onTick === null) {\n return;\n }\n\n // Phase 3 — frame writers (apply this frame's state to the DOM)\n for (const writer of this.#frameWriters) {\n writer();\n }\n\n // Reschedule only if still active (a writer is not expected to stop it, but may).\n if (this.#onTick !== null) {\n this.#scheduleNextTick();\n }\n }\n}\n","import { inject, Injectable } from '@angular/core';\nimport { CursorPosition } from '../models/drag-drop.models';\nimport { DragStateService } from './drag-state.service';\nimport { PositionCalculatorService } from './position-calculator.service';\nimport { DragSchedulerService } from './drag-scheduler.service';\n\n/**\n * Configuration for auto-scroll behavior.\n */\nexport interface AutoScrollConfig {\n /** Distance from edge to start scrolling (in pixels) */\n threshold: number;\n /** Maximum scroll speed in pixels per 60fps frame (about 16.67ms) */\n maxSpeed: number;\n /** Whether to accelerate scroll based on distance from edge */\n accelerate: boolean;\n}\n\n/**\n * Default auto-scroll configuration.\n */\nconst DEFAULT_CONFIG: AutoScrollConfig = {\n threshold: 50,\n maxSpeed: 15,\n accelerate: true,\n};\n\nconst BASE_FRAME_DURATION_MS = 1000 / 60;\nconst MIN_SCROLL_FRAME_SCALE = 1;\nconst MAX_SCROLL_FRAME_SCALE = 6;\n\n/**\n * A container the tick asked to scroll that had no room: the axes it was asked to scroll, and its\n * scroll position and maximum then, to tell when it may have gained room.\n */\ninterface ExhaustedContainer {\n element: HTMLElement;\n vertical: boolean;\n horizontal: boolean;\n scrollTop: number;\n scrollLeft: number;\n maxScrollTop: number;\n maxScrollLeft: number;\n}\n\n/**\n * Service that handles auto-scrolling when dragging near container edges.\n */\n@Injectable({\n providedIn: 'root',\n})\nexport class AutoScrollService {\n readonly #dragState = inject(DragStateService);\n readonly #positionCalculator = inject(PositionCalculatorService);\n readonly #scheduler = inject(DragSchedulerService);\n\n /** Currently registered scrollable containers */\n #scrollableContainers = new Map<\n string,\n {\n element: HTMLElement;\n config: AutoScrollConfig;\n }\n >();\n\n /**\n * Candidate containers ordered innermost (deepest in the DOM) first, so a\n * nested scrollable wins over its ancestors under the cursor. Rebuilt lazily\n * whenever registrations change (containers rarely move mid-drag) and once per\n * drag (see startMonitoring), not per frame.\n */\n #orderedContainers:\n | { id: string; element: HTMLElement; config: AutoScrollConfig; depth: number }[]\n | null = null;\n\n /** Bound reference to #participantTick for stable add/remove with the scheduler. */\n readonly #boundParticipantTick: () => void = () => this.#participantTick();\n\n /** Callback to invoke when scrolling occurs (for placeholder recalculation) */\n #onScrollCallback: (() => void) | null = null;\n\n /** Optional cursor position override for edge detection (bypasses DragState read) */\n #cursorOverride: CursorPosition | null = null;\n\n /** Last tick cursor position for stationary detection */\n #lastTickCursorX = NaN;\n #lastTickCursorY = NaN;\n\n /**\n * The containers the last tick that ran asked to scroll but had no room left: the first\n * #exhaustedCount entries (the objects are reused from tick to tick). A resting cursor skips the\n * tick only while they stay as they were on the axes it asked for: content that grows (rows\n * measured taller, items added), a resize or a scroll can give one room, and the scroll resumes.\n */\n readonly #exhausted: ExhaustedContainer[] = [];\n #exhaustedCount = 0;\n\n /**\n * Last timestamp used to scale per-frame autoscroll distance by elapsed frame time.\n * Scale is intentionally floored at 1 to preserve the existing feel on 60fps+ displays while\n * compensating slower frames that would otherwise under-scroll.\n */\n #lastScrollTimestamp = 0;\n\n /** Reusable direction object for tick loop (avoids per-frame allocation) */\n readonly #tickDirection = { x: 0, y: 0 };\n\n /** Current scroll state */\n readonly #scrollState: {\n containerId: string | null;\n direction: { x: number; y: number };\n speed: number;\n } = {\n containerId: null,\n direction: { x: 0, y: 0 },\n speed: 0,\n };\n\n /**\n * Register a scrollable container for auto-scrolling.\n */\n registerContainer(\n id: string,\n element: HTMLElement,\n config: Partial<AutoScrollConfig> = {},\n ): void {\n this.#scrollableContainers.set(id, {\n element,\n config: { ...DEFAULT_CONFIG, ...config },\n });\n this.#orderedContainers = null;\n }\n\n /**\n * Unregister a scrollable container.\n */\n unregisterContainer(id: string): void {\n this.#scrollableContainers.delete(id);\n this.#orderedContainers = null;\n }\n\n /**\n * Build (or reuse) the candidate list ordered innermost-first by DOM depth.\n *\n * Sorting by absolute DOM depth (descending) is a *total* order, unlike an\n * `element.contains()` comparator which returns 0 for unrelated pairs and so\n * violates transitivity — with ≥3 containers a nested pair separated by an\n * unrelated one in registration order could end up never compared, leaving the\n * ancestor ahead of its descendant. Equal-depth (including unrelated) containers\n * keep registration order via the stable sort, so unrelated lists behave as before.\n */\n #getOrderedContainers(): {\n id: string;\n element: HTMLElement;\n config: AutoScrollConfig;\n depth: number;\n }[] {\n if (this.#orderedContainers) {\n return this.#orderedContainers;\n }\n\n const entries: {\n id: string;\n element: HTMLElement;\n config: AutoScrollConfig;\n depth: number;\n }[] = [];\n for (const [id, { element, config }] of this.#scrollableContainers) {\n // Registration is unconditional (directives can't expose DOM size as a signal, so\n // gating registration on it goes stale — see #27). Filter by live scroll geometry\n // here instead: this list is rebuilt per drag (startMonitoring nulls the cache) and\n // on register/unregister, so a container that grew scrollable after init is picked\n // up on the next drag, and one that shrank stops occupying a candidate slot.\n if (!this.#isScrollable(element)) {\n continue;\n }\n entries.push({ id, element, config, depth: this.#domDepth(element) });\n }\n\n // Deepest first; stable sort keeps registration order on ties.\n entries.sort((a, b) => b.depth - a.depth);\n\n this.#orderedContainers = entries;\n return entries;\n }\n\n /**\n * Whether the element currently has room to scroll on either axis. Read fresh each\n * time the candidate list is (re)built — never cached — so it always reflects the\n * live layout at drag start rather than a stale value captured at registration.\n */\n #isScrollable(element: HTMLElement): boolean {\n return element.scrollHeight > element.clientHeight || element.scrollWidth > element.clientWidth;\n }\n\n /** Number of ancestor elements — the element's absolute depth in the DOM tree. */\n #domDepth(element: HTMLElement): number {\n let depth = 0;\n for (let parent = element.parentElement; parent; parent = parent.parentElement) {\n depth++;\n }\n return depth;\n }\n\n /**\n * Start monitoring for auto-scroll.\n * Registers this service as a tick participant in DragSchedulerService.\n * The scheduler drives the RAF loop; this service handles scroll logic each frame.\n * @param onScroll Optional callback to invoke when scrolling occurs (for placeholder recalculation)\n */\n startMonitoring(onScroll?: () => void): void {\n this.#onScrollCallback = onScroll ?? null;\n // Recompute containment ordering fresh per drag: a registered container may have\n // been reparented (portal/DOM move) since the cache was built, which register/\n // unregister alone wouldn't catch.\n this.#orderedContainers = null;\n this.#scheduler.addParticipant(this.#boundParticipantTick);\n }\n\n /**\n * Stop monitoring for auto-scroll.\n * Removes this service from the scheduler's participant list.\n * Call this when a drag ends.\n */\n stopMonitoring(): void {\n this.#scheduler.removeParticipant(this.#boundParticipantTick);\n this.#onScrollCallback = null;\n this.#cursorOverride = null;\n this.#lastTickCursorX = NaN;\n this.#lastTickCursorY = NaN;\n this.#exhausted.length = 0;\n this.#exhaustedCount = 0;\n this.#lastScrollTimestamp = 0;\n this.#scrollState.containerId = null;\n this.#scrollState.direction.x = 0;\n this.#scrollState.direction.y = 0;\n this.#scrollState.speed = 0;\n }\n\n /**\n * Override the cursor position used for edge detection.\n * When set, #tick() uses this instead of DragStateService.cursorPosition().\n * Used by constrainToContainer to provide a position without grabOffset distortion.\n * @internal\n */\n setCursorOverride(position: CursorPosition): void {\n this.#cursorOverride = position;\n }\n\n /**\n * Participant tick — called by DragSchedulerService each RAF frame.\n *\n * Runs the edge-scroll check and, if a scroll is performed, synchronously\n * invokes #onScrollCallback (the placeholder recalculator) in the same frame.\n * No RAF scheduling here — the scheduler owns the loop.\n */\n #participantTick(): void {\n const cursor = this.#cursorOverride ?? this.#dragState.cursorPosition();\n\n // No cursor yet — nothing to scroll toward.\n if (!cursor) {\n return;\n }\n\n // Skip the container iteration when the cursor hasn't moved and scroll is idle, unless a\n // container it asked to scroll without room has changed since (see #exhausted).\n if (\n cursor.x === this.#lastTickCursorX &&\n cursor.y === this.#lastTickCursorY &&\n !this.isScrolling() &&\n !this.#exhaustedChanged()\n ) {\n return;\n }\n this.#lastTickCursorX = cursor.x;\n this.#lastTickCursorY = cursor.y;\n this.#exhaustedCount = 0;\n\n let scrollPerformed = false;\n // Frame scale is shared across candidates within a tick; computed lazily on\n // the first scroll attempt so stationary/idle frames don't advance the clock.\n let frameScale = 0;\n\n // Candidates are ordered innermost-first: when the deepest container under the\n // cursor is exhausted at its boundary, the loop falls through to its ancestors.\n for (const { id, element, config } of this.#getOrderedContainers()) {\n const rect = element.getBoundingClientRect();\n const isInside = this.#positionCalculator.isInsideContainer(cursor, rect);\n\n if (!isInside) {\n continue;\n }\n\n const nearEdge = this.#positionCalculator.getNearEdge(cursor, rect, config.threshold);\n\n // Reuse the per-frame direction object to avoid allocation.\n const direction = this.#tickDirection;\n direction.x = 0;\n direction.y = 0;\n let maxDistance = 0;\n\n if (nearEdge.top) {\n direction.y = -1;\n maxDistance = Math.max(maxDistance, config.threshold - (cursor.y - rect.top));\n } else if (nearEdge.bottom) {\n direction.y = 1;\n maxDistance = Math.max(maxDistance, config.threshold - (rect.bottom - cursor.y));\n }\n\n if (nearEdge.left) {\n direction.x = -1;\n maxDistance = Math.max(maxDistance, config.threshold - (cursor.x - rect.left));\n } else if (nearEdge.right) {\n direction.x = 1;\n maxDistance = Math.max(maxDistance, config.threshold - (rect.right - cursor.x));\n }\n\n if (direction.x !== 0 || direction.y !== 0) {\n let speed = config.maxSpeed;\n if (config.accelerate) {\n const distanceRatio = maxDistance / config.threshold;\n speed = Math.min(config.maxSpeed, Math.max(1, config.maxSpeed * distanceRatio));\n }\n\n if (frameScale === 0) {\n frameScale = this.#getFrameScale();\n }\n\n // #performScroll reports whether it actually moved the element. Only claim the\n // tick (and stop descending the candidate list) when a scroll really happened —\n // an exhausted container must not block its ancestors from scrolling.\n //\n // Axis independence is per-container: if this container scrolls on *either* axis\n // it claims the whole tick, so a corner where the inner container's Y is exhausted\n // but its X still moves will not additionally apply an ancestor's available Y that\n // same frame. This matches the issue's \"break once a container scrolled\" contract;\n // cross-container axis handoff is intentionally out of scope.\n const scrolled = this.#performScroll(element, direction, frameScale, speed);\n if (scrolled) {\n this.#scrollState.containerId = id;\n this.#scrollState.direction.x = direction.x;\n this.#scrollState.direction.y = direction.y;\n this.#scrollState.speed = speed;\n scrollPerformed = true;\n\n // Notify callback IMMEDIATELY in the same frame (no RAF delay)\n // Delaying via RAF causes cumulative drift during continuous autoscroll\n // because multiple scrolls happen before each delayed callback runs.\n // Note: No ngZone.run() needed here - the callback (DraggableDirective.#recalculatePlaceholder)\n // updates signals and plain fields, and enters the zone itself to emit dragEnd if it ends\n // the drag.\n // It runs after the scroll state is recorded: it may end the drag, and the reset of\n // stopMonitoring() must not be overwritten.\n this.#onScrollCallback?.();\n break;\n }\n // No room in any requested direction: a resting cursor retries it once it changes\n this.#recordExhausted(element, direction);\n }\n }\n\n if (!scrollPerformed) {\n this.#lastScrollTimestamp = 0;\n this.#scrollState.containerId = null;\n this.#scrollState.direction.x = 0;\n this.#scrollState.direction.y = 0;\n this.#scrollState.speed = 0;\n }\n }\n\n /**\n * Perform the actual scroll operation.\n *\n * Each axis is evaluated independently: a boundary-exhausted axis is skipped\n * while the other axis still scrolls (e.g. at a corner where vertical is\n * maxed out but horizontal is available).\n *\n * @returns `true` when at least one axis actually scrolled, `false` when the\n * element was already at its boundary in every requested direction. The\n * caller uses this to fall through to ancestor containers.\n */\n #performScroll(\n element: HTMLElement,\n direction: { x: number; y: number },\n frameScale: number,\n speed: number,\n ): boolean {\n const scrollX = direction.x * speed * frameScale;\n const scrollY = direction.y * speed * frameScale;\n\n // Integer bounds used only as a cheap fast path to skip the assignment.\n // scrollHeight/clientHeight are rounded integers while scrollTop is fractional on\n // WebKit and any non-integer zoom/DPR, so this max can overstate the true one by\n // up to ~1px. It must NOT decide whether a scroll happened — the browser clamps the\n // assignment, so a before/after comparison is the only reliable truth signal.\n // Without it, an element pinned at its fractional max reports `scrolled = true`,\n // permanently claims the tick (blocking ancestor fall-through) and fires the callback\n // every frame against unchanged offsets (the WebKit placeholder-drift family).\n const maxScrollY = element.scrollHeight - element.clientHeight;\n const maxScrollX = element.scrollWidth - element.clientWidth;\n\n let scrolled = false;\n\n // Use direct property assignment for guaranteed synchronous scroll\n // scrollBy() with 'instant' behavior may have async issues in Safari\n if (scrollY !== 0) {\n const canScrollUp = direction.y < 0 && element.scrollTop > 0;\n const canScrollDown = direction.y > 0 && element.scrollTop < maxScrollY;\n if (canScrollUp || canScrollDown) {\n const before = element.scrollTop;\n element.scrollTop += scrollY;\n if (element.scrollTop !== before) {\n scrolled = true;\n }\n }\n }\n\n if (scrollX !== 0) {\n const canScrollLeft = direction.x < 0 && element.scrollLeft > 0;\n const canScrollRight = direction.x > 0 && element.scrollLeft < maxScrollX;\n if (canScrollLeft || canScrollRight) {\n const before = element.scrollLeft;\n element.scrollLeft += scrollX;\n if (element.scrollLeft !== before) {\n scrolled = true;\n }\n }\n }\n\n return scrolled;\n }\n\n /** Record a container that had no room in `direction` (see #exhausted). */\n #recordExhausted(element: HTMLElement, direction: { x: number; y: number }): void {\n const exhausted = (this.#exhausted[this.#exhaustedCount] ??= {\n element,\n vertical: false,\n horizontal: false,\n scrollTop: 0,\n scrollLeft: 0,\n maxScrollTop: 0,\n maxScrollLeft: 0,\n });\n exhausted.element = element;\n exhausted.vertical = direction.y !== 0;\n exhausted.horizontal = direction.x !== 0;\n exhausted.scrollTop = element.scrollTop;\n exhausted.scrollLeft = element.scrollLeft;\n exhausted.maxScrollTop = element.scrollHeight - element.clientHeight;\n exhausted.maxScrollLeft = element.scrollWidth - element.clientWidth;\n this.#exhaustedCount++;\n }\n\n /**\n * Whether a container in #exhausted has scrolled or changed size on an axis it was asked to\n * scroll, so it may have room now.\n */\n #exhaustedChanged(): boolean {\n for (let i = 0; i < this.#exhaustedCount; i++) {\n const exhausted = this.#exhausted[i];\n const { element } = exhausted;\n if (\n (exhausted.vertical &&\n (element.scrollTop !== exhausted.scrollTop ||\n element.scrollHeight - element.clientHeight !== exhausted.maxScrollTop)) ||\n (exhausted.horizontal &&\n (element.scrollLeft !== exhausted.scrollLeft ||\n element.scrollWidth - element.clientWidth !== exhausted.maxScrollLeft))\n ) {\n return true;\n }\n }\n return false;\n }\n\n #getFrameScale(): number {\n const now = performance.now();\n const elapsedMs =\n this.#lastScrollTimestamp === 0 ? BASE_FRAME_DURATION_MS : now - this.#lastScrollTimestamp;\n\n this.#lastScrollTimestamp = now;\n\n return Math.min(\n Math.max(elapsedMs / BASE_FRAME_DURATION_MS, MIN_SCROLL_FRAME_SCALE),\n MAX_SCROLL_FRAME_SCALE,\n );\n }\n\n /**\n * Check if auto-scrolling is currently active.\n */\n isScrolling(): boolean {\n return (\n this.#scrollState.containerId !== null &&\n (this.#scrollState.direction.x !== 0 || this.#scrollState.direction.y !== 0)\n );\n }\n\n /**\n * Get the current scroll direction.\n */\n getScrollDirection(): { x: number; y: number } {\n return this.#scrollState.direction;\n }\n}\n","import { Injectable } from '@angular/core';\n\n/** A CSS property to copy, or a shorthand with the longhands to copy in its place */\ntype StyleToCopy = string | readonly [shorthand: string, longhands: readonly string[]];\n\n/**\n * Service for cloning DOM elements with their computed styles.\n * Used to create visual copies of dragged elements for the drag preview.\n */\n@Injectable({ providedIn: 'root' })\nexport class ElementCloneService {\n /**\n * CSS properties to copy from source to clone, pre-stored in kebab-case.\n * These are the visual properties that affect appearance. Keeping them\n * kebab-case avoids a camelCase→kebab conversion on every property of every\n * node during the recursive clone walk (a drag-start hot path).\n *\n * A shorthand carries more than the longhands listed with it (`background-size`,\n * `font-style`, …), so it is copied first, and the longhands only when the engine can't\n * serialize the shorthand (it gives '' for `font` with `font-variant-ligatures: none`, for\n * example). Copying both would read and write the same values twice.\n */\n readonly #stylesToCopy: readonly StyleToCopy[] = [\n ['background', ['background-color', 'background-image']],\n 'border',\n 'border-radius',\n 'box-shadow',\n 'color',\n ['font', ['font-family', 'font-size', 'font-weight', 'line-height']],\n 'padding',\n 'margin',\n 'display',\n 'flex-direction',\n 'align-items',\n 'justify-content',\n 'gap',\n 'text-align',\n 'text-decoration',\n 'width',\n 'height',\n 'min-width',\n 'min-height',\n 'max-width',\n 'max-height',\n 'overflow',\n 'opacity',\n 'transform',\n 'box-sizing',\n ];\n\n /**\n * Clone an element with its computed styles.\n * Returns an HTMLElement ready for use as a drag preview.\n */\n cloneElement(source: HTMLElement): HTMLElement {\n const clone = source.cloneNode(true) as HTMLElement;\n\n // Apply computed styles as inline styles\n this.#applyComputedStyles(source, clone);\n\n // Handle special elements (canvas, video, etc.)\n this.#handleSpecialElements(source, clone);\n\n // Sanitize the clone for safe use as preview\n this.#sanitizeClone(clone);\n\n return clone;\n }\n\n /**\n * Apply computed styles from source to target element.\n * Recursively applies to all child elements.\n */\n #applyComputedStyles(source: HTMLElement, target: HTMLElement): void {\n const computed = window.getComputedStyle(source);\n\n // Copy essential visual properties (keys are already kebab-case)\n for (const style of this.#stylesToCopy) {\n if (typeof style === 'string') {\n this.#copyStyle(computed, target, style);\n continue;\n }\n // The longhands only when the shorthand was not copied: the engine gave no value, or the\n // clone rejected it. A shorthand sets all its longhands, so reading one back tells (the\n // shorthand itself would be serialized again to be read). The clone may carry that\n // longhand inline from the source, so it goes first.\n const [shorthand, longhands] = style;\n target.style.removeProperty(longhands[0]);\n if (\n !this.#copyStyle(computed, target, shorthand) ||\n !target.style.getPropertyValue(longhands[0])\n ) {\n for (const longhand of longhands) {\n this.#copyStyle(computed, target, longhand);\n }\n }\n }\n\n // Disable animations and transitions on clone\n target.style.animation = 'none';\n target.style.transition = 'none';\n\n // Recursively apply to children\n const sourceChildren = source.children;\n const targetChildren = target.children;\n\n for (let i = 0; i < sourceChildren.length && i < targetChildren.length; i++) {\n const sourceChild = sourceChildren[i];\n const targetChild = targetChildren[i];\n\n if (sourceChild instanceof HTMLElement && targetChild instanceof HTMLElement) {\n this.#applyComputedStyles(sourceChild, targetChild);\n }\n }\n }\n\n /**\n * Copy one computed property to the target's inline style. Returns whether the engine gave a\n * value for it.\n */\n #copyStyle(computed: CSSStyleDeclaration, target: HTMLElement, property: string): boolean {\n const value = computed.getPropertyValue(property);\n if (!value) {\n return false;\n }\n target.style.setProperty(property, value);\n return true;\n }\n\n /**\n * Handle special elements that require extra processing.\n */\n #handleSpecialElements(source: HTMLElement, clone: HTMLElement): void {\n // Handle canvas elements - copy current content\n const sourceCanvases = source.querySelectorAll('canvas');\n const cloneCanvases = clone.querySelectorAll('canvas');\n\n sourceCanvases.forEach((srcCanvas, i) => {\n const cloneCanvas = cloneCanvases[i] as HTMLCanvasElement;\n if (cloneCanvas) {\n const ctx = cloneCanvas.getContext('2d');\n if (ctx) {\n cloneCanvas.width = srcCanvas.width;\n cloneCanvas.height = srcCanvas.height;\n ctx.drawImage(srcCanvas, 0, 0);\n }\n }\n });\n\n // Handle video elements - replace with poster or placeholder\n const videos = clone.querySelectorAll('video');\n videos.forEach((video) => {\n const poster = video.poster;\n if (poster) {\n const img = document.createElement('img');\n img.src = poster;\n img.style.width = '100%';\n img.style.height = '100%';\n img.style.objectFit = 'cover';\n video.replaceWith(img);\n } else {\n // Create a placeholder\n const placeholder = document.createElement('div');\n placeholder.style.cssText = `\n width: 100%;\n height: 100%;\n display: flex;\n align-items: center;\n justify-content: center;\n `;\n video.replaceWith(placeholder);\n }\n });\n\n // Handle iframes - replace with placeholder\n const iframes = clone.querySelectorAll('iframe');\n iframes.forEach((iframe) => {\n const placeholder = document.createElement('div');\n const iframeStyles = window.getComputedStyle(iframe);\n placeholder.style.width = iframeStyles.width;\n placeholder.style.height = iframeStyles.height;\n placeholder.style.display = 'flex';\n placeholder.style.alignItems = 'center';\n placeholder.style.justifyContent = 'center';\n iframe.replaceWith(placeholder);\n });\n }\n\n /**\n * Sanitize the clone to prevent interaction issues.\n */\n #sanitizeClone(clone: HTMLElement): void {\n // Remove draggable directive attributes\n clone.removeAttribute('vdndDraggable');\n clone.removeAttribute('data-draggable-id');\n clone.removeAttribute('data-droppable-id');\n\n // Remove Angular-specific attributes\n const angularAttrs = Array.from(clone.attributes).filter(\n (attr) => attr.name.startsWith('ng-') || attr.name.startsWith('_ng'),\n );\n angularAttrs.forEach((attr) => clone.removeAttribute(attr.name));\n\n // Process all descendant elements\n const allElements = clone.querySelectorAll('*');\n allElements.forEach((el) => {\n if (!(el instanceof HTMLElement)) return;\n\n // Remove event-related attributes\n const attrs = Array.from(el.attributes);\n attrs.forEach((attr) => {\n if (\n attr.name.startsWith('on') ||\n attr.name.startsWith('(') ||\n attr.name.startsWith('ng-') ||\n attr.name.startsWith('_ng')\n ) {\n el.removeAttribute(attr.name);\n }\n });\n\n // Remove draggable attributes from children too\n el.removeAttribute('vdndDraggable');\n el.removeAttribute('data-draggable-id');\n el.removeAttribute('data-droppable-id');\n });\n\n // Disable interactive elements\n const interactiveElements = clone.querySelectorAll(\n 'button, input, textarea, select, a, [contenteditable]',\n );\n interactiveElements.forEach((el) => {\n if (el instanceof HTMLElement) {\n el.style.pointerEvents = 'none';\n el.setAttribute('tabindex', '-1');\n el.setAttribute('aria-hidden', 'true');\n el.setAttribute('disabled', 'true');\n }\n });\n\n // A checked radio joins its group as soon as the clone is connected, which unchecks the\n // radio in the source item. Without a name the cloned radios belong to no group.\n clone.querySelectorAll('input[type=\"radio\"][name]').forEach((radio) => {\n radio.removeAttribute('name');\n });\n\n // Remove focus styling classes that might interfere\n clone.classList.remove('vdnd-draggable-dragging');\n clone.classList.remove('vdnd-draggable-disabled');\n }\n}\n","import { computed, inject, Injectable, signal } from '@angular/core';\nimport { DragStateService } from './drag-state.service';\nimport { DraggedItem, END_OF_LIST, GrabOffset } from '../models/drag-drop.models';\n\n/**\n * Service for managing keyboard-initiated drag operations.\n * Works in conjunction with DragStateService to provide keyboard drag functionality.\n */\n@Injectable({\n providedIn: 'root',\n})\nexport class KeyboardDragService {\n readonly #dragState = inject(DragStateService);\n\n /** Total item count for the current droppable (set by droppable on keyboard drag start) */\n readonly #totalItemCount = signal<number>(0);\n\n /** Per-droppable callbacks that scroll the placeholder into view (see `registerRevealer`) */\n readonly #revealers = new Map<string, () => void>();\n\n /** Whether a keyboard drag is currently active */\n readonly isActive = computed(\n () => this.#dragState.isKeyboardDrag() && this.#dragState.isDragging(),\n );\n\n /** Current target index during keyboard navigation */\n readonly targetIndex = computed(() => this.#dragState.keyboardTargetIndex());\n\n /** Source index where the drag started */\n readonly sourceIndex = computed(() => this.#dragState.sourceIndex());\n\n /** Current active droppable ID */\n readonly activeDroppableId = computed(() => this.#dragState.activeDroppableId());\n\n /**\n * Start a keyboard drag operation.\n */\n startKeyboardDrag(\n item: DraggedItem,\n sourceIndex: number,\n totalItemCount: number,\n activeDroppableId: string,\n ): void {\n this.#totalItemCount.set(totalItemCount);\n\n // For keyboard drag, we position the preview at the element's location\n // We use a grab offset of 0,0 since we're not grabbing at a specific point\n const grabOffset: GrabOffset = { x: 0, y: 0 };\n\n // Get the element's position for the cursor position\n // This positions the preview at the element's original location\n const rect = item.element.getBoundingClientRect();\n const cursorPosition = { x: rect.left, y: rect.top };\n\n // Same-list adjustment: at start, targetIndex equals sourceIndex\n // Since sourceIndex >= sourceIndex is always true, add 1 to placeholderIndex\n // This accounts for the hidden item shifting everything up visually\n const initialPlaceholderIndex = sourceIndex + 1;\n\n this.#dragState.startDrag(\n item,\n cursorPosition,\n grabOffset,\n null, // no axis lock for keyboard drag\n activeDroppableId,\n END_OF_LIST,\n initialPlaceholderIndex,\n sourceIndex,\n true, // isKeyboardDrag\n );\n }\n\n /**\n * Move to a specific index during keyboard drag.\n * Returns the clamped target index.\n */\n moveToIndex(targetIndex: number): number {\n if (!this.isActive()) {\n return targetIndex;\n }\n\n const maxIndex = this.#maxTargetIndex(this.activeDroppableId());\n const clampedIndex = Math.max(0, Math.min(targetIndex, maxIndex));\n\n this.#dragState.setKeyboardTargetIndex(clampedIndex);\n this.#revealActivePlaceholder();\n\n return clampedIndex;\n }\n\n /**\n * Move up by one position (ArrowUp).\n * Returns the new target index.\n */\n moveUp(): number {\n const currentTarget = this.targetIndex() ?? 0;\n return this.moveToIndex(currentTarget - 1);\n }\n\n /**\n * Move down by one position (ArrowDown).\n * Returns the new target index.\n */\n moveDown(): number {\n const currentTarget = this.targetIndex() ?? 0;\n return this.moveToIndex(currentTarget + 1);\n }\n\n /**\n * Move to an adjacent droppable (ArrowLeft/ArrowRight).\n * The droppable registry is managed externally.\n */\n moveToDroppable(droppableId: string, targetIndex: number, totalItemCount: number): void {\n if (!this.isActive()) {\n return;\n }\n\n this.#totalItemCount.set(totalItemCount);\n const clampedIndex = Math.max(0, Math.min(targetIndex, this.#maxTargetIndex(droppableId)));\n this.#dragState.setKeyboardActiveDroppable(droppableId, clampedIndex);\n this.#revealActivePlaceholder();\n }\n\n /**\n * Register the callback that scrolls a droppable's placeholder into view. It runs\n * synchronously on every keyboard move into or within that droppable, so a drop that\n * follows before the next render still lands inside the rendered range.\n */\n registerRevealer(droppableId: string, reveal: () => void): void {\n this.#revealers.set(droppableId, reveal);\n }\n\n /**\n * Unregister a droppable's reveal callback. Ignored if another callback has since been\n * registered under the same ID.\n */\n unregisterRevealer(droppableId: string, reveal: () => void): void {\n if (this.#revealers.get(droppableId) === reveal) {\n this.#revealers.delete(droppableId);\n }\n }\n\n /**\n * Complete the keyboard drag (Space or Enter to drop).\n */\n completeKeyboardDrag(): void {\n if (!this.isActive()) {\n return;\n }\n\n this.#dragState.endDrag();\n }\n\n /**\n * Cancel the keyboard drag (Escape).\n */\n cancelKeyboardDrag(): void {\n if (!this.isActive()) {\n return;\n }\n\n this.#dragState.cancelDrag();\n }\n\n /**\n * Update the total item count (when navigating to a new list).\n */\n setTotalItemCount(count: number): void {\n this.#totalItemCount.set(count);\n }\n\n #revealActivePlaceholder(): void {\n const droppableId = this.activeDroppableId();\n if (droppableId !== null) {\n this.#revealers.get(droppableId)?.();\n }\n }\n\n /**\n * Last valid target index in the given droppable. Targets use the drop convention (the item's\n * final index after it leaves its source), so the source list ends at `totalItemCount - 1`,\n * while any other list can be appended to at `totalItemCount`.\n */\n #maxTargetIndex(droppableId: string | null): number {\n const totalItems = this.#totalItemCount();\n const isSourceList =\n droppableId !== null && droppableId === this.#dragState.sourceDroppableId();\n return isSourceList ? Math.max(0, totalItems - 1) : totalItems;\n }\n}\n","import { computed, Injectable, OnDestroy, signal } from '@angular/core';\n\n/**\n * Service that manages a shared overlay container appended to `document.body`.\n *\n * Elements placed inside the overlay container escape any ancestor CSS `transform`,\n * `perspective`, or `filter` that would create a new containing block for\n * `position: fixed` children. This ensures viewport-relative positioning works\n * correctly regardless of where the consuming component sits in the DOM tree.\n *\n * Mirrors the strategy used by Angular CDK's `OverlayContainer`.\n */\n@Injectable({\n providedIn: 'root',\n})\nexport class OverlayContainerService implements OnDestroy {\n #containerElement: HTMLElement | null = null;\n\n /** Number of mounted drag previews currently rendering via a custom template. */\n readonly #templatePreviewCount = signal(0);\n\n /**\n * Whether at least one mounted drag preview renders via a custom template.\n *\n * When true, DraggableDirective/KeyboardDragHandler skip the expensive\n * drag-start element clone: the clone would never be shown because the\n * template takes precedence (see DragPreviewComponent).\n */\n readonly hasTemplatePreview = computed(() => this.#templatePreviewCount() > 0);\n\n /**\n * Register (`active = true`) or unregister (`active = false`) a preview that\n * renders via a custom template. Calls must be balanced per preview instance.\n */\n setTemplatePreviewActive(active: boolean): void {\n this.#templatePreviewCount.update((count) => Math.max(0, count + (active ? 1 : -1)));\n }\n\n /**\n * Returns the shared overlay container element, lazily creating it on first access.\n * Returns `null` in non-browser environments (SSR).\n */\n getContainerElement(): HTMLElement | null {\n if (typeof document === 'undefined') {\n return null;\n }\n\n if (!this.#containerElement) {\n this.#containerElement = document.createElement('div');\n this.#containerElement.classList.add('vdnd-overlay-container');\n document.body.appendChild(this.#containerElement);\n }\n\n return this.#containerElement;\n }\n\n ngOnDestroy(): void {\n this.#containerElement?.remove();\n this.#containerElement = null;\n }\n}\n","import { inject, Injectable } from '@angular/core';\nimport { type CursorPosition, END_OF_LIST, type GrabOffset } from '../models/drag-drop.models';\nimport { PositionCalculatorService } from './position-calculator.service';\nimport type { VirtualScrollStrategy } from '../models/virtual-scroll-strategy';\n\ninterface DroppableCache {\n droppableId: string | null;\n containerType: 'viewport' | 'virtualScroll' | 'virtualContent' | 'fallback';\n scrollContainer: HTMLElement;\n virtualScrollElement: HTMLElement | null;\n virtualContentElement: HTMLElement | null;\n scrollableParent: HTMLElement | null;\n itemHeight: number;\n isConstrainedToContainer: boolean;\n strategy: VirtualScrollStrategy | null;\n}\n\n/** Where a droppable's rows are, relative to the element they scroll in. */\nexport interface DroppableScrollGeometry {\n /** Viewport rect of the element the rows scroll in */\n rect: DOMRect;\n /**\n * How far the rows are scrolled: a row's offset from the first row (as in\n * `VirtualScrollStrategy.getOffsetForIndex`) is `rowTop - rect.top + scrollTop`. Space reserved\n * above the rows (`contentOffset`) is already subtracted.\n */\n scrollTop: number;\n /**\n * Whether the container virtualizes its rows itself (`vdnd-virtual-scroll`,\n * `vdnd-virtual-content`), so a row's index can't be counted from the rows before it. A\n * viewport's rows are virtualized by `*vdndVirtualFor`, which registers a strategy.\n */\n isVirtual: boolean;\n}\n\n@Injectable({\n providedIn: 'root',\n})\nexport class DragIndexCalculatorService {\n readonly #positionCalculator = inject(PositionCalculatorService);\n\n /** Registered strategies by droppable ID */\n readonly #strategies = new Map<string, VirtualScrollStrategy>();\n\n /** Cached droppable metadata to avoid repeated DOM queries during drag */\n readonly #droppableCache = new Map<HTMLElement, DroppableCache>();\n\n /**\n * Register a virtual scroll strategy for a droppable.\n * Used by virtual scroll components to provide dynamic height lookups.\n */\n registerStrategy(droppableId: string, strategy: VirtualScrollStrategy): void {\n this.#strategies.set(droppableId, strategy);\n }\n\n /**\n * Unregister a strategy when the droppable is destroyed.\n */\n unregisterStrategy(droppableId: string): void {\n this.#strategies.delete(droppableId);\n }\n\n /**\n * Get the registered strategy for a droppable ID.\n * Used by draggable to calculate source index with variable heights.\n */\n getStrategyForDroppable(droppableId: string): VirtualScrollStrategy | undefined {\n return this.#strategies.get(droppableId);\n }\n\n clearCache(): void {\n this.#droppableCache.clear();\n }\n\n #resolveDroppable(droppableElement: HTMLElement, draggedItemHeight: number): DroppableCache {\n const cached = this.#droppableCache.get(droppableElement);\n if (cached) return cached;\n\n const isViewport = droppableElement.hasAttribute('data-virtual-viewport');\n const virtualScrollElement = droppableElement.querySelector(\n 'vdnd-virtual-scroll',\n ) as HTMLElement | null;\n const virtualContentElement = this.#findVirtualContent(droppableElement);\n\n let containerType: DroppableCache['containerType'];\n let scrollContainer: HTMLElement;\n let scrollableParent: HTMLElement | null = null;\n\n if (isViewport) {\n // The viewport scrolls its own rows. Checked first so a list nested in a row is not\n // mistaken for this one.\n containerType = 'viewport';\n scrollContainer = droppableElement;\n } else if (virtualScrollElement) {\n containerType = 'virtualScroll';\n scrollContainer = virtualScrollElement;\n } else if (virtualContentElement) {\n containerType = 'virtualContent';\n scrollableParent = virtualContentElement.closest('.vdnd-scrollable') as HTMLElement | null;\n scrollContainer = scrollableParent ?? virtualContentElement;\n } else {\n containerType = 'fallback';\n scrollContainer = droppableElement;\n }\n\n const droppableId = this.#positionCalculator.getDroppableId(droppableElement);\n const strategy = (droppableId ? this.#strategies.get(droppableId) : null) ?? null;\n\n const configuredHeight =\n virtualScrollElement?.getAttribute('data-item-height') ??\n virtualContentElement?.getAttribute('data-item-height');\n const parsedHeight = configuredHeight ? parseFloat(configuredHeight) : Number.NaN;\n const itemHeight = Number.isFinite(parsedHeight)\n ? parsedHeight\n : this.#getDraggedItemHeightFallback(draggedItemHeight, 50);\n\n const isConstrainedToContainer = droppableElement.hasAttribute('data-constrain-to-container');\n\n const entry: DroppableCache = {\n droppableId,\n containerType,\n scrollContainer,\n virtualScrollElement,\n virtualContentElement,\n scrollableParent,\n itemHeight,\n isConstrainedToContainer,\n strategy,\n };\n\n this.#droppableCache.set(droppableElement, entry);\n return entry;\n }\n\n getTotalItemCount(args: {\n droppableElement: HTMLElement;\n isSameList: boolean;\n draggedItemHeight: number;\n }): number {\n return this.#getTotalItemCount(args.droppableElement, args.draggedItemHeight);\n }\n\n /**\n * Live scroll geometry of a droppable's rows (see {@link DroppableScrollGeometry}). The same\n * measurement places the placeholder and finds the dragged item's source index.\n */\n getScrollGeometry(\n droppableElement: HTMLElement,\n draggedItemHeight: number,\n ): DroppableScrollGeometry {\n return this.#getScrollGeometry(this.#resolveDroppable(droppableElement, draggedItemHeight));\n }\n\n calculatePlaceholderIndex(args: {\n droppableElement: HTMLElement;\n position: CursorPosition;\n /**\n * Unused: the index probe is direction-independent (capped center + midpoint refinement).\n * Kept so callers don't change.\n */\n previousPosition: CursorPosition | null;\n grabOffset: GrabOffset | null;\n draggedItemHeight: number;\n sourceDroppableId: string | null;\n sourceIndex: number | null;\n }): { index: number; placeholderId: string } {\n const {\n droppableElement,\n position,\n grabOffset,\n draggedItemHeight,\n sourceDroppableId,\n sourceIndex,\n } = args;\n\n // Resolve cached metadata (DOM queries run once per droppable per drag session)\n const cache = this.#resolveDroppable(droppableElement, draggedItemHeight);\n\n // Live reads: getBoundingClientRect() and scrollTop change during scroll\n const { rect, scrollTop: currentScrollTop } = this.#getScrollGeometry(cache);\n\n const {\n strategy,\n itemHeight,\n droppableId: currentDroppableId,\n isConstrainedToContainer,\n } = cache;\n\n // Calculate preview center position mathematically\n // The preview is positioned at: cursorPosition - grabOffset (see drag-preview.component.ts)\n // So preview center = cursorPosition.y - grabOffset.y + previewHeight/2\n // Using math avoids Safari's stale getBoundingClientRect() issue during autoscroll\n // Use actual dragged item height when available (important for dynamic heights)\n const previewHeight = this.#getDraggedItemHeightFallback(draggedItemHeight, itemHeight);\n const previewTopY = position.y - (grabOffset?.y ?? 0);\n const previewBottomY = previewTopY + previewHeight;\n const previewCenterY = previewTopY + previewHeight / 2;\n\n // Capped center probe: use preview center but limit how deep the probe reaches.\n // The cap prevents a tall preview (e.g. 120px among 60px items) from overshooting\n // multiple positions — the center would land 2+ items away, but the cap keeps it\n // within one item of the top edge.\n const indexProbeY = Math.min(previewCenterY, previewTopY + itemHeight / 2);\n\n // Convert to visual index\n const relativeY = indexProbeY - rect.top + currentScrollTop;\n\n // Determine same-list drag info before strategy branch\n const isSameList = sourceDroppableId !== null && sourceDroppableId === currentDroppableId;\n const sourceIndexValue = isSameList ? (sourceIndex ?? -1) : -1;\n\n let visualIndex: number;\n if (strategy) {\n visualIndex = strategy.findIndexAtOffset(relativeY);\n\n // Midpoint refinement for variable heights:\n // Only advance past an item when the preview top has crossed its midpoint.\n // Without this, a short preview entering a tall item's range triggers\n // displacement at ~20% overlap, which looks like unnatural overlapping.\n const topRelativeY = previewTopY - rect.top + currentScrollTop;\n const targetTop = strategy.getOffsetForIndex(visualIndex);\n const targetBottom = strategy.getOffsetForIndex(visualIndex + 1);\n const targetMidpoint = (targetTop + targetBottom) / 2;\n if (topRelativeY >= targetMidpoint) {\n visualIndex += 1;\n }\n } else {\n // Fixed height: simple division\n visualIndex = Math.floor(relativeY / itemHeight);\n }\n\n // Same-list +1 adjustment:\n // - No strategy: always adjust when visual index is at/after source\n // - Strategy: adjust only if exclusion has not been applied yet\n // (prevents an off-by-one window during early drag updates)\n let placeholderIndex = visualIndex;\n if (isSameList && sourceIndexValue >= 0 && visualIndex >= sourceIndexValue) {\n const needsAdjustment = !strategy || !this.#isSourceIndexExcluded(strategy, sourceIndexValue);\n if (needsAdjustment) {\n placeholderIndex = visualIndex + 1;\n }\n }\n\n // Get total items using cached strategy to avoid duplicate DOM queries\n let totalItems: number;\n const cachedItemCount = strategy?.getItemCount();\n if (cachedItemCount !== undefined && Number.isFinite(cachedItemCount)) {\n totalItems = Math.max(0, cachedItemCount);\n } else {\n totalItems = this.#getTotalItemCount(droppableElement, draggedItemHeight, cache);\n }\n\n // Edge detection: allow dropping at the END of the list when cursor is near bottom edge.\n // Due to max scroll limits, the math alone can't reach totalItems when the list is longer\n // than the viewport. If cursor is in the bottom portion of the container and we're at\n // or past the last visible slot, snap to totalItems.\n const cursorRelativeToBottom = rect.bottom - previewCenterY;\n const isNearBottomEdge = cursorRelativeToBottom < itemHeight;\n if (isNearBottomEdge && placeholderIndex >= totalItems - 1) {\n placeholderIndex = totalItems;\n }\n\n // When the preview is constrained to the container bounds, large dragged items can\n // cover the first/last slots while their center never reaches them. Snap to edges\n // using preview bounds so top/bottom drops remain reachable.\n if (isConstrainedToContainer) {\n const droppableRect = droppableElement.getBoundingClientRect();\n const edgeTolerance = 2;\n const distanceToTop = Math.abs(previewTopY - droppableRect.top);\n const distanceToBottom = Math.abs(droppableRect.bottom - previewBottomY);\n\n if (distanceToTop <= edgeTolerance && distanceToTop <= distanceToBottom) {\n placeholderIndex = 0;\n } else if (distanceToBottom <= edgeTolerance) {\n placeholderIndex = totalItems;\n }\n }\n\n // Clamp to valid range\n placeholderIndex = Math.max(0, Math.min(placeholderIndex, totalItems));\n\n return { index: placeholderIndex, placeholderId: END_OF_LIST };\n }\n\n #getScrollGeometry(cache: DroppableCache): DroppableScrollGeometry {\n const { containerType, scrollContainer } = cache;\n const rect = scrollContainer.getBoundingClientRect();\n const isVirtual = containerType === 'virtualScroll' || containerType === 'virtualContent';\n\n switch (containerType) {\n case 'viewport':\n return {\n rect,\n scrollTop: scrollContainer.scrollTop - this.#readContentOffset(scrollContainer),\n isVirtual,\n };\n case 'virtualContent':\n // Without a vdndScrollable parent the content element itself is measured, unscrolled\n return cache.scrollableParent\n ? {\n rect,\n scrollTop:\n scrollContainer.scrollTop - this.#readContentOffset(cache.virtualContentElement),\n isVirtual,\n }\n : { rect, scrollTop: 0, isVirtual };\n default:\n return { rect, scrollTop: scrollContainer.scrollTop, isVirtual };\n }\n }\n\n /** The `data-content-offset` (px reserved above the rows) of a virtual container, or 0. */\n #readContentOffset(element: HTMLElement | null): number {\n const offset = parseFloat(element?.getAttribute('data-content-offset') ?? '');\n return Number.isFinite(offset) ? offset : 0;\n }\n\n /**\n * The number of items in a droppable. With `cache`, the drag's resolved metadata, the virtual\n * containers it knows are not looked up in the DOM again: this runs on every frame of a drag\n * over a list without a registered strategy.\n */\n #getTotalItemCount(\n droppableElement: HTMLElement,\n draggedItemHeight: number,\n cache?: DroppableCache,\n ): number {\n // Check if a registered strategy exists\n const droppableId = this.#positionCalculator.getDroppableId(droppableElement);\n const strategy = droppableId ? this.#strategies.get(droppableId) : null;\n const strategyItemCount = strategy?.getItemCount();\n if (strategyItemCount !== undefined && Number.isFinite(strategyItemCount)) {\n return Math.max(0, strategyItemCount);\n }\n\n // Check for embedded virtual scroll component\n const virtualScroll = cache\n ? cache.virtualScrollElement\n : droppableElement.querySelector('vdnd-virtual-scroll');\n if (virtualScroll) {\n // Use data-total-items attribute if available (always the true N)\n const totalItemsAttr = virtualScroll.getAttribute('data-total-items');\n if (totalItemsAttr) {\n const count = parseInt(totalItemsAttr, 10);\n if (Number.isFinite(count)) {\n return count;\n }\n }\n\n // Fallback: Use the spacer's height, NOT scrollHeight, to determine item count.\n // scrollHeight can be inflated by absolutely-positioned elements like the placeholder.\n const spacer = virtualScroll.querySelector(\n '.vdnd-virtual-scroll-spacer',\n ) as HTMLElement | null;\n const configuredHeight = virtualScroll.getAttribute('data-item-height');\n const itemHeight = configuredHeight\n ? parseInt(configuredHeight, 10)\n : this.#getDraggedItemHeightFallback(draggedItemHeight, 50);\n\n let totalHeight: number;\n if (spacer) {\n // Get the spacer's explicit height (set via Angular binding)\n totalHeight = parseFloat(spacer.style.height) || 0;\n } else {\n // Fallback: use scrollHeight if spacer not found\n totalHeight = (virtualScroll as HTMLElement).scrollHeight;\n }\n\n // When strategy exists, spacer height already accounts for exclusion.\n // Don't apply same-list +1 adjustment — strategy handles it.\n if (strategy) {\n const count = Math.round(totalHeight / itemHeight);\n return count;\n }\n\n // Spacer height reflects full N items (getTotalHeight no longer excludes)\n const count = Math.floor(totalHeight / itemHeight);\n return count;\n }\n\n // Check for page-level scroll (vdnd-virtual-content)\n const virtualContent = cache\n ? cache.virtualContentElement\n : this.#findVirtualContent(droppableElement);\n if (virtualContent) {\n // Prefer explicit total items attribute (works for both fixed and dynamic heights)\n const totalItemsAttr = (virtualContent as HTMLElement).getAttribute('data-total-items');\n if (totalItemsAttr) {\n const count = parseInt(totalItemsAttr, 10);\n if (Number.isFinite(count)) {\n // data-total-items is the true total N (derived from strategy item count)\n return count;\n }\n }\n\n // Fallback: use spacer height to determine total items\n const spacer = virtualContent.querySelector('.vdnd-content-spacer') as HTMLElement | null;\n if (spacer) {\n const totalHeight = parseFloat(spacer.style.height) || 0;\n const configuredHeight = virtualContent.getAttribute('data-item-height');\n const itemHeight = configuredHeight\n ? parseInt(configuredHeight, 10)\n : this.#getDraggedItemHeightFallback(draggedItemHeight, 72);\n return Math.floor(totalHeight / itemHeight);\n }\n }\n\n // Fallback for non-virtual scroll — querySelectorAll finds all N items\n // (including the hidden dragged item), so no adjustment needed\n const items = droppableElement.querySelectorAll('[data-draggable-id]');\n return items.length;\n }\n\n /** The `vdnd-virtual-content` the droppable is or is inside (page-level scroll), if any. */\n #findVirtualContent(droppableElement: HTMLElement): HTMLElement | null {\n return droppableElement.matches('vdnd-virtual-content')\n ? droppableElement\n : droppableElement.closest<HTMLElement>('vdnd-virtual-content');\n }\n\n #getDraggedItemHeightFallback(height: number, fallback: number): number {\n return Number.isFinite(height) && height > 0 ? height : fallback;\n }\n\n /**\n * Detect whether a strategy has already excluded the source index.\n *\n * With exclusion applied, the source slot collapses in visual space:\n * offset(sourceIndex + 1) <= offset(sourceIndex). Without exclusion,\n * the next offset is strictly greater.\n */\n #isSourceIndexExcluded(strategy: VirtualScrollStrategy, sourceIndex: number): boolean {\n if (sourceIndex < 0) {\n return false;\n }\n\n const sourceOffset = strategy.getOffsetForIndex(sourceIndex);\n const nextOffset = strategy.getOffsetForIndex(sourceIndex + 1);\n\n return nextOffset <= sourceOffset;\n }\n}\n","import { ChangeDetectionStrategy, Component, input } from '@angular/core';\n\n/**\n * Renders an empty placeholder that takes up space in the document flow.\n *\n * This component is used internally by virtual scroll containers to show\n * where an item will be dropped. It's rendered inline with items and\n * takes up the same vertical space as an item.\n *\n * The placeholder is just empty space - no borders, no background.\n * Consumers can style it via CSS if desired.\n */\n@Component({\n selector: 'vdnd-drag-placeholder',\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n class: 'vdnd-drag-placeholder vdnd-drag-placeholder-visible',\n '[style.height.px]': 'itemHeight()',\n },\n styles: `\n :host {\n display: block;\n pointer-events: none;\n }\n `,\n template: ``,\n})\nexport class DragPlaceholderComponent {\n /** Item height for sizing */\n itemHeight = input.required<number>();\n}\n","import { NgZone, type WritableSignal } from '@angular/core';\n\n/** A layout value, or 0 where there is no layout (server rendering leaves them undefined). */\nfunction layoutValue(value: number): number {\n return Number.isFinite(value) ? value : 0;\n}\n\nexport function bindRafThrottledScrollTopSignal(options: {\n element: HTMLElement;\n ngZone: NgZone;\n scrollTop: WritableSignal<number>;\n thresholdPx?: number;\n onCommit?: (scrollTop: number) => void;\n}): () => void {\n const { element, ngZone, scrollTop, thresholdPx = 5, onCommit } = options;\n\n let pendingRaf: number | null = null;\n let lastCommittedScrollTop = layoutValue(element.scrollTop);\n\n const onScroll = () => {\n if (pendingRaf !== null) {\n return;\n }\n\n const currentScrollTop = element.scrollTop;\n if (Math.abs(currentScrollTop - lastCommittedScrollTop) < thresholdPx) {\n return;\n }\n\n pendingRaf = requestAnimationFrame(() => {\n pendingRaf = null;\n const finalScrollTop = element.scrollTop;\n if (Math.abs(finalScrollTop - lastCommittedScrollTop) >= thresholdPx) {\n lastCommittedScrollTop = finalScrollTop;\n scrollTop.set(finalScrollTop);\n onCommit?.(finalScrollTop);\n }\n });\n };\n\n ngZone.runOutsideAngular(() => {\n element.addEventListener('scroll', onScroll, { passive: true });\n });\n\n scrollTop.set(lastCommittedScrollTop);\n\n return () => {\n if (pendingRaf !== null) {\n cancelAnimationFrame(pendingRaf);\n pendingRaf = null;\n }\n element.removeEventListener('scroll', onScroll);\n };\n}\n\nexport function bindResizeObserverHeightSignal(options: {\n element: HTMLElement;\n ngZone: NgZone;\n height: WritableSignal<number>;\n minDeltaPx?: number;\n}): () => void {\n const { element, ngZone, height, minDeltaPx = 1 } = options;\n\n if (typeof ResizeObserver === 'undefined') {\n height.set(layoutValue(element.clientHeight));\n return () => undefined;\n }\n\n let observer: ResizeObserver | null = null;\n\n ngZone.runOutsideAngular(() => {\n observer = new ResizeObserver((entries) => {\n for (const entry of entries) {\n const nextHeight = entry.contentRect.height;\n if (Math.abs(nextHeight - height()) > minDeltaPx) {\n height.set(nextHeight);\n }\n }\n });\n observer.observe(element);\n });\n\n height.set(layoutValue(element.clientHeight));\n\n return () => {\n observer?.disconnect();\n observer = null;\n };\n}\n","import { DestroyRef, effect, inject } from '@angular/core';\nimport { type AutoScrollConfig, AutoScrollService } from '../services/auto-scroll.service';\n\ninterface AutoScrollRegistrationOptions {\n autoScrollService: AutoScrollService;\n getElement: () => HTMLElement;\n getId: () => string;\n enabled: () => boolean;\n config: () => Partial<AutoScrollConfig>;\n canRegister?: () => boolean;\n}\n\nexport function createAutoScrollRegistration(options: AutoScrollRegistrationOptions): void {\n const destroyRef = inject(DestroyRef);\n let registeredId: string | null = null;\n\n const unregisterCurrent = (): void => {\n if (registeredId === null) {\n return;\n }\n\n options.autoScrollService.unregisterContainer(registeredId);\n registeredId = null;\n };\n\n effect(() => {\n const enabled = options.enabled();\n const id = options.getId();\n const config = options.config();\n const canRegister = options.canRegister?.() ?? true;\n\n if (!enabled || !canRegister) {\n unregisterCurrent();\n return;\n }\n\n if (registeredId !== null && registeredId !== id) {\n unregisterCurrent();\n }\n\n options.autoScrollService.registerContainer(id, options.getElement(), config);\n registeredId = id;\n });\n\n destroyRef.onDestroy(unregisterCurrent);\n}\n","import type { VirtualScrollStrategy } from '../models/virtual-scroll-strategy';\nimport { DynamicHeightStrategy } from './dynamic-height.strategy';\nimport { FixedHeightStrategy } from './fixed-height.strategy';\n\n/**\n * Give a list's strategy its items: `count` of them, with the track keys `keys` returns (the\n * list's own array, which it goes on reading).\n *\n * - FixedHeightStrategy's `setItemKeys` only counts the keys: it gets the count, and the keys are\n * never computed.\n * - DynamicHeightStrategy's copies the keys: it gets the list's array.\n * - Any other `setItemKeys` (a strategy of the consumer's own, or a subclass that overrides it)\n * gets a copy, which it may keep and change.\n * @internal\n */\nexport function setStrategyItems(\n strategy: VirtualScrollStrategy,\n count: number,\n keys: () => unknown[],\n): void {\n if (\n strategy instanceof FixedHeightStrategy &&\n strategy.setItemKeys === FixedHeightStrategy.prototype.setItemKeys\n ) {\n strategy.setItemCount(count);\n } else if (\n strategy instanceof DynamicHeightStrategy &&\n strategy.setItemKeys === DynamicHeightStrategy.prototype.setItemKeys\n ) {\n strategy.setItemKeys(keys());\n } else {\n strategy.setItemKeys(keys().slice());\n }\n}\n","/**\n * Query by an exact attribute value without interpolating consumer data into a CSS selector.\n *\n * CSS attribute selectors need string-specific escaping that differs from `CSS.escape()`.\n * Filtering candidates by attribute presence avoids selector syntax errors for IDs containing\n * quotes, brackets, backslashes, or other selector-sensitive characters.\n */\nexport function queryByAttribute<T extends Element>(\n root: ParentNode,\n attributeName: string,\n attributeValue: string,\n): T | null {\n const candidates = root.querySelectorAll<T>(`[${attributeName}]`);\n\n for (const candidate of candidates) {\n if (candidate.getAttribute(attributeName) === attributeValue) {\n return candidate;\n }\n }\n\n return null;\n}\n\n/**\n * The elements carrying an attribute, by its value (the first in document order when several\n * share one, as `queryByAttribute` finds). One query for many lookups, where `queryByAttribute`\n * scans every candidate on each call.\n */\nexport function mapByAttribute<T extends Element>(\n root: ParentNode,\n attributeName: string,\n): Map<string, T> {\n const elements = new Map<string, T>();\n for (const candidate of root.querySelectorAll<T>(`[${attributeName}]`)) {\n const value = candidate.getAttribute(attributeName)!;\n if (!elements.has(value)) {\n elements.set(value, candidate);\n }\n }\n return elements;\n}\n\nexport function queryAllByAttribute<T extends Element>(\n root: ParentNode,\n attributeName: string,\n attributeValue: string,\n): T[] {\n return Array.from(root.querySelectorAll<T>(`[${attributeName}]`)).filter(\n (candidate) => candidate.getAttribute(attributeName) === attributeValue,\n );\n}\n","import { afterNextRender, Injector } from '@angular/core';\nimport {\n DEFAULT_SHIFT_DURATION,\n DEFAULT_SHIFT_EASING,\n type VdndAnimationConfig,\n} from '../tokens/animation-config.token';\n\n/** A rendered element and the identity it currently represents (trackBy key). */\nexport type ShiftAnimationEntry = readonly [key: unknown, element: HTMLElement];\n\ninterface MeasuredPosition {\n key: unknown;\n x: number;\n y: number;\n}\n\ninterface RunningShift {\n animation: Animation;\n /** Starting offset of the animation (it eases from here to 0) */\n x: number;\n y: number;\n}\n\n/** Layout changes smaller than this are ignored (sub-pixel rounding noise). */\nconst MIN_SHIFT_PX = 0.5;\n\n/**\n * FLIP animator for items displaced by the drag placeholder.\n *\n * Call `beforeUpdate()` before the DOM reflects a new drag/placeholder state. When the\n * placeholder moved (or the drag ended), it snapshots every rendered element's visual position, then after\n * the render measures again and plays a compositor-only `transform` animation from the\n * old position to the new one.\n *\n * Positions are measured relative to the scroll content, so scrolling (including\n * programmatic scroll in the same tick) never animates. Measurements include any\n * in-flight animation, so a new displacement retargets from where the item currently\n * is instead of stacking or jumping. Elements whose target did not change keep their\n * running animation untouched.\n * @internal\n */\nexport class ShiftAnimator {\n readonly #config: VdndAnimationConfig;\n readonly #injector: Injector;\n readonly #getScrollElement: () => HTMLElement | null;\n readonly #getEntries: () => Iterable<ShiftAnimationEntry>;\n\n readonly #running = new Map<HTMLElement, RunningShift>();\n #snapshot: Map<HTMLElement, MeasuredPosition> | null = null;\n #reducedMotionQuery: MediaQueryList | null | undefined;\n #wasDragging = false;\n #lastPlaceholderIndex = -1;\n\n constructor(options: {\n config: VdndAnimationConfig;\n injector: Injector;\n getScrollElement: () => HTMLElement | null;\n getEntries: () => Iterable<ShiftAnimationEntry>;\n }) {\n this.#config = options.config;\n this.#injector = options.injector;\n this.#getScrollElement = options.getScrollElement;\n this.#getEntries = options.getEntries;\n }\n\n /**\n * Notify the animator of the drag state about to be rendered.\n * @param placeholderIndex placeholder index in this list, or -1 when not shown here\n */\n beforeUpdate(isDragging: boolean, placeholderIndex: number): void {\n const wasDragging = this.#wasDragging;\n const previousIndex = this.#lastPlaceholderIndex;\n this.#wasDragging = isDragging;\n this.#lastPlaceholderIndex = placeholderIndex;\n\n if (!isDragging) {\n // Drop/cancel: one last pass slides rows from their drag layout into the committed\n // order. After a drop the rows usually already sit in their final slots, so in-flight\n // slides simply finish; after a cancel the displaced rows slide back.\n // A pending snapshot already holds this tick's \"before\".\n if (!wasDragging || this.#snapshot) {\n return;\n }\n if (!this.#isEnabled()) {\n this.cancelAll();\n return;\n }\n this.#snapshot = this.#measure();\n afterNextRender(() => this.#play(), { injector: this.#injector });\n return;\n }\n\n // Drag start renders the placeholder in the hidden item's slot — nothing moves.\n // A pending snapshot means another update already captured this tick's \"before\".\n if (!wasDragging || placeholderIndex === previousIndex || this.#snapshot) {\n return;\n }\n if (!this.#isEnabled()) {\n return;\n }\n\n this.#snapshot = this.#measure();\n afterNextRender(() => this.#play(), { injector: this.#injector });\n }\n\n /** Stop the shift animation on an element (e.g. before its view is recycled). */\n cancel(element: HTMLElement): void {\n const running = this.#running.get(element);\n if (!running) return;\n this.#running.delete(element);\n running.animation.cancel();\n }\n\n /** Stop every running shift animation. */\n cancelAll(): void {\n for (const running of this.#running.values()) {\n running.animation.cancel();\n }\n this.#running.clear();\n }\n\n #isEnabled(): boolean {\n if (this.#duration() <= 0) return false;\n if (typeof Element === 'undefined' || typeof Element.prototype.animate !== 'function') {\n return false;\n }\n return !this.#prefersReducedMotion();\n }\n\n #duration(): number {\n return this.#config.shiftDuration ?? DEFAULT_SHIFT_DURATION;\n }\n\n #prefersReducedMotion(): boolean {\n if (this.#reducedMotionQuery === undefined) {\n this.#reducedMotionQuery =\n typeof matchMedia === 'function' ? matchMedia('(prefers-reduced-motion: reduce)') : null;\n }\n return this.#reducedMotionQuery?.matches ?? false;\n }\n\n /** Scroll-content origin, so positions are independent of the scroll offset. */\n #origin(): { x: number; y: number } {\n const scrollElement = this.#getScrollElement();\n if (!scrollElement) return { x: 0, y: 0 };\n const rect = scrollElement.getBoundingClientRect();\n return { x: rect.left - scrollElement.scrollLeft, y: rect.top - scrollElement.scrollTop };\n }\n\n #measure(): Map<HTMLElement, MeasuredPosition> {\n const origin = this.#origin();\n const positions = new Map<HTMLElement, MeasuredPosition>();\n for (const [key, element] of this.#getEntries()) {\n const rect = element.getBoundingClientRect();\n // Hidden (display: none) elements, such as the dragged item, have no box.\n if (rect.width === 0 && rect.height === 0) continue;\n positions.set(element, { key, x: rect.left - origin.x, y: rect.top - origin.y });\n }\n return positions;\n }\n\n #play(): void {\n const first = this.#snapshot;\n this.#snapshot = null;\n if (!first) return;\n\n const last = this.#measure();\n const stale: HTMLElement[] = [];\n const shifts: { element: HTMLElement; x: number; y: number }[] = [];\n\n // Read phase — no writes until every element is measured.\n for (const [element, to] of last) {\n const from = first.get(element);\n if (!from || !Object.is(from.key, to.key)) {\n // Newly rendered or recycled for another item: must not animate from a stale offset.\n stale.push(element);\n continue;\n }\n\n const dx = from.x - to.x;\n const dy = from.y - to.y;\n if (Math.abs(dx) < MIN_SHIFT_PX && Math.abs(dy) < MIN_SHIFT_PX) {\n continue;\n }\n\n // Both measurements include the in-flight offset, so the new animation must\n // start from that offset plus the layout delta to continue from the current spot.\n const current = this.#currentOffset(element);\n shifts.push({ element, x: dx + current.x, y: dy + current.y });\n }\n\n // Write phase\n for (const element of stale) {\n this.cancel(element);\n }\n for (const shift of shifts) {\n this.#start(shift.element, shift.x, shift.y);\n }\n }\n\n #currentOffset(element: HTMLElement): { x: number; y: number } {\n const running = this.#running.get(element);\n // Effect-level easing makes `progress` the eased progress, i.e. the fraction travelled.\n const progress = running?.animation.effect?.getComputedTiming().progress;\n if (!running || progress === null || progress === undefined) {\n return { x: 0, y: 0 };\n }\n const remaining = 1 - progress;\n return { x: running.x * remaining, y: running.y * remaining };\n }\n\n #start(element: HTMLElement, x: number, y: number): void {\n this.#running.get(element)?.animation.cancel();\n\n const animation = element.animate(\n [{ transform: `translate(${x}px, ${y}px)` }, { transform: 'translate(0px, 0px)' }],\n {\n duration: this.#duration(),\n easing: this.#config.shiftEasing ?? DEFAULT_SHIFT_EASING,\n // Layer on top of any transform the consumer already applies to the item.\n composite: 'add',\n },\n );\n this.#running.set(element, { animation, x, y });\n animation.onfinish = () => {\n if (this.#running.get(element)?.animation === animation) {\n this.#running.delete(element);\n }\n };\n }\n}\n","import {\n DEFAULT_DROP_DURATION,\n DEFAULT_DROP_EASING,\n type VdndAnimationConfig,\n} from '../tokens/animation-config.token';\nimport { queryByAttribute } from './attribute-selectors';\n\n/** Where the ghost should land, and the element that stands there. */\nexport interface DropAnimationTarget {\n /** The dropped item's rendered element (hidden until the ghost lands) */\n element: HTMLElement;\n /** Its viewport rect */\n rect: DOMRect;\n}\n\n/** The elements drop animations hide, with the animation hiding each */\nconst hiddenTargets = new Map<Element, Animation>();\n\n/**\n * Show again an element a drop animation hides, if one of these nodes holds it. A virtual list\n * calls it for the row it pools: that row's element renders another item next.\n * @internal\n */\nexport function revealDropTargetIn(nodes: readonly Node[]): void {\n for (const [element, animation] of hiddenTargets) {\n if (nodes.some((node) => node.contains(element))) {\n hiddenTargets.delete(element);\n animation.cancel();\n }\n }\n}\n\n/**\n * Plays the drop (\"settle\") animation: the drag preview glides from where it was released\n * into the dropped item's final position, while that item stays invisible underneath.\n *\n * Purely visual. The drag state and the drop events are already final when it starts, so it\n * never delays or changes a drop. Without a target (the item is not rendered, or scrolled out\n * of view) the ghost fades out where it was released.\n * @internal\n */\nexport class DropAnimator {\n readonly #config: VdndAnimationConfig;\n\n #ghostAnimation: Animation | null = null;\n #hidden: { element: Element; animation: Animation } | null = null;\n\n /** The reduced-motion media query, created on first use (null without `matchMedia`) */\n #reducedMotionQuery: MediaQueryList | null | undefined;\n\n constructor(config: VdndAnimationConfig) {\n this.#config = config;\n }\n\n /** Whether a drop animation would play right now (duration, WAAPI, reduced motion). */\n isEnabled(): boolean {\n if (this.#duration() <= 0) return false;\n if (typeof Element === 'undefined' || typeof Element.prototype.animate !== 'function') {\n return false;\n }\n return !this.#prefersReducedMotion();\n }\n\n /**\n * Animate `ghost` onto `target` (or fade it out without one), then call `onDone`.\n * `onDone` is not called when the animation is cancelled.\n */\n play(ghost: HTMLElement, target: DropAnimationTarget | null, onDone: () => void): void {\n this.cancel();\n\n const timing: KeyframeAnimationOptions = {\n duration: this.#duration(),\n easing: this.#config.dropEasing ?? DEFAULT_DROP_EASING,\n fill: 'forwards',\n };\n\n let ghostAnimation: Animation;\n if (target) {\n const from = ghost.getBoundingClientRect();\n const dx = target.rect.left - from.left;\n const dy = target.rect.top - from.top;\n // Travel on top of the preview's own position transform (width/height must not be\n // composited, so the base transform is repeated instead of using composite: 'add').\n const base = ghost.style.transform;\n ghostAnimation = ghost.animate(\n [\n {\n transform: `${base} translate(0px, 0px)`,\n width: `${from.width}px`,\n height: `${from.height}px`,\n },\n {\n transform: `${base} translate(${dx}px, ${dy}px)`,\n width: `${target.rect.width}px`,\n height: `${target.rect.height}px`,\n },\n ],\n timing,\n );\n // Keep the real item invisible until the ghost lands on it, so it is never seen twice.\n const hideAnimation = target.element.animate([{ opacity: 0 }, { opacity: 0 }], {\n duration: timing.duration,\n });\n this.#hidden = { element: target.element, animation: hideAnimation };\n hiddenTargets.set(target.element, hideAnimation);\n } else {\n ghostAnimation = ghost.animate([{ opacity: 1 }, { opacity: 0 }], timing);\n }\n\n this.#ghostAnimation = ghostAnimation;\n ghostAnimation.onfinish = () => {\n if (this.#ghostAnimation !== ghostAnimation) return;\n this.cancel();\n onDone();\n };\n }\n\n /** Stop the running animation immediately and reveal the real item. */\n cancel(): void {\n const ghostAnimation = this.#ghostAnimation;\n const hidden = this.#hidden;\n this.#ghostAnimation = null;\n this.#hidden = null;\n ghostAnimation?.cancel();\n if (hidden) {\n if (hiddenTargets.get(hidden.element) === hidden.animation) {\n hiddenTargets.delete(hidden.element);\n }\n hidden.animation.cancel();\n }\n }\n\n #duration(): number {\n return this.#config.dropDuration ?? DEFAULT_DROP_DURATION;\n }\n\n /** One media query for every drop: it is live, so it follows a change of the preference. */\n #prefersReducedMotion(): boolean {\n if (this.#reducedMotionQuery === undefined) {\n this.#reducedMotionQuery =\n typeof matchMedia === 'function' ? matchMedia('(prefers-reduced-motion: reduce)') : null;\n }\n return this.#reducedMotionQuery?.matches ?? false;\n }\n}\n\n/**\n * Find the rendered element of a dropped item: first in the droppable it was dropped on, then\n * in the one it came from (a drop the consumer rejected or has not committed yet leaves it\n * there). Returns null when it is not rendered, or rendered but scrolled out of its list's view.\n *\n * `getDroppable` resolves a droppable ID to its element (the droppable registry lookup).\n */\nexport function findDropTarget(\n draggableId: string,\n droppableIds: readonly (string | null | undefined)[],\n getDroppable: (droppableId: string) => HTMLElement | null,\n): DropAnimationTarget | null {\n for (const droppableId of droppableIds) {\n if (!droppableId) continue;\n const droppable = getDroppable(droppableId);\n const element = droppable\n ? queryByAttribute<HTMLElement>(droppable, 'data-draggable-id', draggableId)\n : null;\n if (!droppable || !element) continue;\n\n const rect = element.getBoundingClientRect();\n // Hidden, or virtualized/scrolled out of the list's visible box: nowhere to land.\n if (rect.width === 0 && rect.height === 0) return null;\n const bounds = droppable.getBoundingClientRect();\n const visible =\n rect.bottom > bounds.top &&\n rect.top < bounds.bottom &&\n rect.right > bounds.left &&\n rect.left < bounds.right;\n return visible ? { element, rect } : null;\n }\n return null;\n}\n","import {\n afterNextRender,\n afterRenderEffect,\n AfterViewChecked,\n AfterViewInit,\n ChangeDetectionStrategy,\n Component,\n ComponentRef,\n computed,\n createComponent,\n effect,\n ElementRef,\n EmbeddedViewRef,\n EnvironmentInjector,\n inject,\n Injector,\n input,\n isDevMode,\n NgZone,\n OnChanges,\n OnDestroy,\n OnInit,\n PLATFORM_ID,\n signal,\n TemplateRef,\n untracked,\n viewChild,\n ViewContainerRef,\n} from '@angular/core';\nimport { isPlatformBrowser } from '@angular/common';\nimport { DragStateService } from '../services/drag-state.service';\nimport type { DraggedItem } from '../models/drag-drop.models';\nimport { AutoScrollConfig, AutoScrollService } from '../services/auto-scroll.service';\nimport { KeyboardDragService } from '../services/keyboard-drag.service';\nimport { DragIndexCalculatorService } from '../services/drag-index-calculator.service';\nimport { DragPlaceholderComponent } from './drag-placeholder.component';\nimport {\n bindRafThrottledScrollTopSignal,\n bindResizeObserverHeightSignal,\n} from '../utils/dom-signal-bindings';\nimport { createAutoScrollRegistration } from '../utils/auto-scroll-registration';\nimport type { VirtualScrollStrategy } from '../models/virtual-scroll-strategy';\nimport { FixedHeightStrategy } from '../strategies/fixed-height.strategy';\nimport { DynamicHeightStrategy } from '../strategies/dynamic-height.strategy';\nimport { setStrategyItems } from '../strategies/strategy-items';\nimport { mapByAttribute } from '../utils/attribute-selectors';\nimport { VDND_ANIMATION_CONFIG } from '../tokens/animation-config.token';\nimport { ShiftAnimationEntry, ShiftAnimator } from '../utils/shift-animator';\nimport { revealDropTargetIn } from '../utils/drop-animator';\n\n/**\n * Context provided to the item template.\n */\nexport interface VirtualScrollItemContext<T> {\n /** The item data */\n $implicit: T;\n /** The item's index in the original array */\n index: number;\n /** Whether this item is \"sticky\" (always rendered) */\n isSticky: boolean;\n}\n\n/** An entry of the rendered list: an item's row, or the placeholder. */\ninterface RenderedEntry<T> {\n type: 'item' | 'placeholder';\n data: T | null;\n index: number;\n isSticky: boolean;\n isDragging: boolean;\n}\n\n/** A rendered row: the item template's view and the track key it was created for. */\ninterface RowView<T> {\n key: unknown;\n view: EmbeddedViewRef<VirtualScrollItemContext<T>>;\n}\n\n/**\n * How many views of rows that left a list stay pooled for rows that come in (recycleRows). A\n * scroll step reuses the views it pools right away; the pool keeps the rest, for example when\n * fewer rows render after the list shrinks.\n */\nconst MAX_POOLED_ROWS = 10;\n\n/** `Node.DOCUMENT_POSITION_FOLLOWING`, without the `Node` global (servers have none) */\nconst DOCUMENT_POSITION_FOLLOWING = 4;\n\n/**\n * The node that comes first in the DOM. A view's `rootNodes` list a control flow block's anchor\n * before the nodes rendered in it, which the DOM puts before the anchor.\n */\nfunction firstInDocumentOrder(nodes: Node[]): Node | null {\n let first: Node | null = null;\n for (const node of nodes) {\n if (first === null || node.compareDocumentPosition(first) & DOCUMENT_POSITION_FOLLOWING) {\n first = node;\n }\n }\n return first;\n}\n\n/**\n * Which values belong to a longest increasing subsequence of `values` (negative values never\n * do). For rows: the views that can stay where they are while the others move around them, as\n * few as possible. A moved row loses focus and restarts its CSS transitions.\n */\nfunction longestIncreasingRun(values: number[]): boolean[] {\n // tails[k]: the index of the smallest value that ends an increasing run of length k + 1\n const tails: number[] = [];\n const previous = new Array<number>(values.length).fill(-1);\n for (let i = 0; i < values.length; i++) {\n const value = values[i];\n if (value < 0) continue;\n let low = 0;\n let high = tails.length;\n while (low < high) {\n const middle = (low + high) >> 1;\n if (values[tails[middle]] < value) {\n low = middle + 1;\n } else {\n high = middle;\n }\n }\n previous[i] = low > 0 ? tails[low - 1] : -1;\n tails[low] = i;\n }\n\n const inRun = new Array<boolean>(values.length).fill(false);\n for (let i = tails.length > 0 ? tails[tails.length - 1] : -1; i >= 0; i = previous[i]) {\n inRun[i] = true;\n }\n return inRun;\n}\n\n/**\n * A virtual scroll container that only renders visible items.\n *\n * Key features:\n * - Only renders items within the visible viewport plus an overscan buffer\n * - Supports \"sticky\" items that are always rendered (used for dragged items)\n * - Uses spacer divs to maintain correct scroll height\n * - Integrates with the drag-and-drop system\n * - Automatic height detection via ResizeObserver when containerHeight is not provided\n * - Supports dynamic item heights via `dynamicItemHeight` input\n *\n * @example\n * ```html\n * <!-- With fixed height items -->\n * <vdnd-virtual-scroll\n * [items]=\"items()\"\n * [itemHeight]=\"50\"\n * [containerHeight]=\"400\"\n * [trackByFn]=\"trackById\">\n * <ng-template let-item let-index=\"index\">\n * <div class=\"item\">{{ item.name }}</div>\n * </ng-template>\n * </vdnd-virtual-scroll>\n *\n * <!-- With dynamic height items -->\n * <vdnd-virtual-scroll\n * [items]=\"items()\"\n * [itemHeight]=\"50\"\n * [dynamicItemHeight]=\"true\"\n * [containerHeight]=\"400\"\n * [trackByFn]=\"trackById\">\n * <ng-template let-item let-index=\"index\">\n * <div class=\"item\">{{ item.description }}</div>\n * </ng-template>\n * </vdnd-virtual-scroll>\n * ```\n */\n@Component({\n selector: 'vdnd-virtual-scroll',\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n class: 'vdnd-virtual-scroll',\n '[style.height.px]': 'containerHeight() ?? null',\n '[attr.data-item-height]': 'itemHeight()',\n '[attr.data-total-items]': 'items().length',\n },\n // No bindings: the effects render the rows, the placeholder, the spacer height and the content\n // offset (see #render). A signal read here would re-render every row whenever it changes.\n template: `\n <!-- Single spacer maintains scroll height -->\n <div #spacer class=\"vdnd-virtual-scroll-spacer\"></div>\n\n <!-- Content wrapper positioned via GPU-accelerated transform -->\n <div #contentWrapper class=\"vdnd-virtual-scroll-content-wrapper\">\n <ng-container #rows />\n </div>\n `,\n styles: `\n :host {\n display: block;\n overflow: auto;\n position: relative;\n /* Disable browser scroll anchoring - this prevents scroll position from being\n adjusted when the DOM changes (e.g., when placeholder position updates).\n Without this, autoscroll UP would fight with browser's scroll restoration. */\n overflow-anchor: none;\n }\n\n .vdnd-virtual-scroll-spacer {\n /* Invisible spacer that maintains scroll height */\n position: absolute;\n top: 0;\n left: 0;\n width: 1px;\n visibility: hidden;\n pointer-events: none;\n }\n\n .vdnd-virtual-scroll-content-wrapper {\n /* GPU-accelerated positioning */\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n will-change: transform;\n }\n `,\n})\nexport class VirtualScrollContainerComponent<T>\n implements OnChanges, OnInit, AfterViewInit, AfterViewChecked, OnDestroy\n{\n readonly #dragState = inject(DragStateService);\n readonly #elementRef = inject(ElementRef<HTMLElement>);\n readonly #autoScrollService = inject(AutoScrollService);\n readonly #dragIndexCalculator = inject(DragIndexCalculatorService);\n readonly #keyboardDrag = inject(KeyboardDragService);\n readonly #ngZone = inject(NgZone);\n readonly #injector = inject(Injector);\n readonly #environmentInjector = inject(EnvironmentInjector);\n readonly #isBrowser = isPlatformBrowser(inject(PLATFORM_ID));\n\n /** Cleanup function for scroll listener */\n #scrollCleanup: (() => void) | null = null;\n #resizeCleanup: (() => void) | null = null;\n\n /** ResizeObserver for dynamic height measurement (only in dynamic height mode) */\n readonly #itemResizeObserver = signal<ResizeObserver | null>(null);\n\n /** Map from observed HTMLElement to its trackBy key */\n readonly #observedElements = new WeakMap<HTMLElement, unknown>();\n /** Stable mapping from rendered key to observed element for unobserve cleanup */\n readonly #observedElementByKey = new Map<unknown, HTMLElement>();\n\n /** Measured height from ResizeObserver (used when containerHeight is not provided) */\n readonly #measuredHeight = signal(0);\n\n /** Slides items displaced by the placeholder (only when VDND_ANIMATION_CONFIG is provided) */\n readonly #shiftAnimator = this.#createShiftAnimator();\n\n /** The template's spacer (cannot use ES private with viewChild) */\n private readonly spacer = viewChild<ElementRef<HTMLElement>>('spacer');\n\n /** The template's content wrapper (cannot use ES private with viewChild) */\n private readonly contentWrapper = viewChild<ElementRef<HTMLElement>>('contentWrapper');\n\n /** Where #renderRows inserts the rows (cannot use ES private with viewChild) */\n private readonly rowOutlet = viewChild('rows', { read: ViewContainerRef });\n\n /** Rendered rows, in DOM order */\n #rows: RowView<T>[] = [];\n\n /** The entries the rendered rows show */\n #rowEntries: RenderedEntry<T>[] | null = null;\n\n /** The template the rendered rows were created from */\n #rowTemplate: TemplateRef<VirtualScrollItemContext<T>> | null = null;\n\n /** The track function that gave the rendered rows their keys */\n #rowTrackBy: unknown = null;\n\n /** Views of rows that left, detached, to render rows that come in (recycleRows) */\n #rowPool: EmbeddedViewRef<VirtualScrollItemContext<T>>[] = [];\n\n /**\n * Set while this component's view is about to be checked in the current change detection pass:\n * from an input change (ngOnChanges, which runs before its effects; the first render included)\n * until the check (ngAfterViewChecked). That check renders every row.\n */\n #viewCheckPending = false;\n\n /** The placeholder, created on its first render and reused */\n #placeholder: ComponentRef<DragPlaceholderComponent> | null = null;\n\n /** Height last set on the placeholder */\n #placeholderHeightSet: number | null = null;\n\n /** Content offset last written to the content wrapper */\n #contentTransformSet: string | null = null;\n\n /** Whether duplicate track keys were reported (once per list) */\n #warnedDuplicateKeys = false;\n\n /** The row keys last checked for duplicates (checked again when the rows change) */\n #rowKeysChecked: unknown[] | null = null;\n\n /** Template for rendering each item - passed as input instead of content child for reliability */\n itemTemplate = input.required<TemplateRef<VirtualScrollItemContext<T>>>();\n\n /** Unique ID for this scroll container (used for auto-scroll registration) */\n scrollContainerId = input<string>();\n\n /** Whether auto-scroll is enabled when dragging near edges */\n autoScrollEnabled = input<boolean>(true);\n\n /** Auto-scroll configuration */\n autoScrollConfig = input<Partial<AutoScrollConfig>>({});\n\n /** Array of items to render */\n items = input.required<T[]>();\n\n /** Height of each item in pixels (used as estimate in dynamic mode) */\n itemHeight = input.required<number>();\n\n /**\n * Enable dynamic item height mode.\n * When true, items are auto-measured via ResizeObserver and `itemHeight`\n * serves as the initial estimate for unmeasured items.\n */\n dynamicItemHeight = input<boolean>(false);\n\n /**\n * Height of the container in pixels.\n * If not provided, the container will automatically measure its height from CSS.\n * This allows you to set the height via CSS (e.g., flex, height: 100%, etc.)\n * and the component will adapt automatically, including on resize.\n */\n containerHeight = input<number>();\n\n /**\n * Effective height used for calculations.\n * Uses explicit containerHeight if provided, otherwise uses measured height.\n */\n readonly effectiveHeight = computed(() => this.containerHeight() ?? this.#measuredHeight());\n\n /** Number of items to render above/below the visible area */\n overscan = input<number>(3);\n\n /** IDs of items that should always be rendered (e.g., dragged items) */\n stickyItemIds = input<string[]>([]);\n\n /** Function to get a unique ID from an item */\n itemIdFn = input.required<(item: T) => string>();\n\n /**\n * Track-by function for the @for loop.\n * Optional - if not provided, will be derived from itemIdFn.\n */\n trackByFn = input<(index: number, item: T) => string | number>();\n\n /**\n * ID of the droppable this virtual scroll belongs to.\n * Required for placeholder positioning.\n */\n droppableId = input<string>();\n\n /**\n * Reuse the views of rows that scroll out to render the rows that scroll in, instead of\n * destroying them and creating new ones. Scrolling creates fewer components and elements, but\n * a row's components, element and DOM state (focus aside) then carry over to other items.\n * @default false\n */\n recycleRows = input<boolean>(false);\n\n /**\n * Whether to automatically add the dragged item to the sticky list.\n * This ensures the dragged item remains visible during virtual scrolling.\n * @default true\n */\n autoStickyDraggedItem = input<boolean>(true);\n\n // ========== Strategy ==========\n\n /** The virtual scroll strategy, created based on dynamicItemHeight input */\n readonly #strategy = computed<VirtualScrollStrategy>(() => {\n const height = this.itemHeight();\n return this.dynamicItemHeight()\n ? new DynamicHeightStrategy(height)\n : new FixedHeightStrategy(height);\n });\n\n /**\n * Effective track-by function - uses provided trackByFn or derives from itemIdFn.\n */\n protected readonly effectiveTrackByFn = computed(() => {\n const userFn = this.trackByFn();\n if (userFn) return userFn;\n\n const idFn = this.itemIdFn();\n return (_index: number, item: T) => idFn(item);\n });\n\n /**\n * Track function for rendered entries (items + placeholder).\n */\n protected trackEntry(\n _index: number,\n entry: { type: 'item' | 'placeholder'; data: T | null; index: number },\n ): string | number {\n if (entry.type === 'placeholder') {\n return '__placeholder__';\n }\n const trackFn = this.effectiveTrackByFn();\n return trackFn(entry.index, entry.data as T);\n }\n\n /**\n * Effective sticky item IDs - combines user-provided IDs with auto-sticky dragged item.\n */\n protected readonly effectiveStickyIds = computed(() => {\n const userIds = this.stickyItemIds();\n\n if (!this.autoStickyDraggedItem()) {\n return userIds;\n }\n\n const draggedId = this.draggedItemId();\n if (!draggedId) {\n return userIds;\n }\n\n // Avoid creating new array if dragged ID is already in the list\n if (userIds.includes(draggedId)) {\n return userIds;\n }\n\n return [...userIds, draggedId];\n });\n\n /** Current scroll position */\n readonly #scrollTop = signal(0);\n\n /** Total height of all items (for scrollbar) */\n protected readonly totalHeight = computed(() => {\n const count = this.items().length;\n const strategy = this.#strategy();\n strategy.version();\n return strategy.getTotalHeight(count);\n });\n\n /** First visible item index */\n readonly #firstVisibleIndex = computed(() => {\n const strategy = this.#strategy();\n strategy.version();\n return strategy.getFirstVisibleIndex(this.#scrollTop());\n });\n\n /** Number of items visible in the viewport */\n readonly #visibleCount = computed(() => {\n const height = this.effectiveHeight();\n const strategy = this.#strategy();\n strategy.version();\n return strategy.getVisibleCount(this.#firstVisibleIndex(), height);\n });\n\n /** Range of items to render (with overscan) */\n readonly #renderRange = computed(() => {\n const first = this.#firstVisibleIndex();\n const visible = this.#visibleCount();\n const overscan = this.overscan();\n const total = this.items().length;\n\n const start = Math.max(0, first - overscan);\n const end = Math.min(total - 1, first + visible + overscan);\n\n return { start, end };\n });\n\n /** Transform offset for content wrapper (position of first rendered item) */\n protected readonly contentTransform = computed(() => {\n const { start } = this.#renderRange();\n const strategy = this.#strategy();\n strategy.version();\n\n const offset = strategy.getOffsetForIndex(start);\n return `translateY(${offset}px)`;\n });\n\n /** The ID of the currently dragged item (if any) */\n protected readonly draggedItemId = computed(() => {\n return this.#dragState.draggedItem()?.draggableId ?? null;\n });\n\n /**\n * Every item's ID, in order. Computed once per items change, and only when something reads it:\n * a dynamic-height strategy, a drag, or a sticky item outside the rendered rows. A fixed-height\n * strategy needs only the item count.\n */\n readonly #itemIds = computed(() => {\n const idFn = this.itemIdFn();\n return this.items().map((item) => idFn(item));\n });\n\n /**\n * Index of each item ID (the last, when several share one), for the sticky items outside the\n * rendered rows. Built on first use, so an items change (a drop) builds none.\n */\n readonly #itemIndexMap = computed(() => {\n const ids = this.#itemIds();\n const map = new Map<string, number>();\n for (let i = 0; i < ids.length; i++) {\n map.set(ids[i], i);\n }\n return map;\n });\n\n /**\n * The index of the currently dragged item in the items array (-1 if not found or not dragging).\n * Found without the index map, which only this lookup would need on a drag: a drag that started\n * in another list has no item here (IDs are unique across lists), the index where the drag found\n * its item is checked next, and only then every item ID is searched.\n */\n readonly #draggedItemIndex = computed(() => {\n const draggedId = this.draggedItemId();\n if (!draggedId) return -1;\n\n const droppableId = this.droppableId();\n const sourceDroppableId = this.#dragState.sourceDroppableId();\n if (droppableId && sourceDroppableId && droppableId !== sourceDroppableId) return -1;\n\n const sourceIndex = this.#dragState.sourceIndex();\n const items = this.items();\n if (\n sourceIndex !== null &&\n sourceIndex >= 0 &&\n sourceIndex < items.length &&\n this.itemIdFn()(items[sourceIndex]) === draggedId\n ) {\n return sourceIndex;\n }\n return this.#itemIds().lastIndexOf(draggedId);\n });\n\n /** Memoized Set of sticky IDs - rebuilt only when effectiveStickyIds() changes */\n readonly #stickyIdsSet = computed(() => new Set(this.effectiveStickyIds()));\n\n /** Whether the placeholder should be shown in this container */\n protected readonly shouldShowPlaceholder = computed(() => {\n if (!this.#dragState.isDragging()) return false;\n return this.#dragState.activeDroppableId() === this.droppableId();\n });\n\n /** The placeholder index when placeholder should be shown */\n protected readonly placeholderIndex = computed(() => {\n if (!this.shouldShowPlaceholder()) return -1;\n return this.#dragState.placeholderIndex() ?? -1;\n });\n\n /** Height for the placeholder — use dragged item's actual height in dynamic mode */\n protected readonly placeholderHeight = computed(() => {\n if (this.dynamicItemHeight()) {\n const draggedItemHeight = this.#dragState.draggedItem()?.height;\n if (draggedItemHeight && draggedItemHeight > 0) return draggedItemHeight;\n }\n return this.itemHeight();\n });\n\n /**\n * Rows to render: the items in range, then the sticky items outside it. Independent of the\n * placeholder, so a placeholder move leaves the rows as they are.\n */\n readonly #renderedRows = computed(() => {\n const items = this.items();\n const { start, end } = this.#renderRange();\n const stickyIds = this.#stickyIdsSet();\n const idFn = this.itemIdFn();\n const draggedId = this.draggedItemId();\n\n const result: RenderedEntry<T>[] = [];\n const renderedIds = new Set<string>();\n\n // Add all items in the visible range\n for (let i = start; i <= end && i < items.length; i++) {\n const item = items[i];\n const id = idFn(item);\n result.push({\n type: 'item',\n data: item,\n index: i,\n isSticky: stickyIds.has(id),\n isDragging: id === draggedId,\n });\n renderedIds.add(id);\n }\n\n // Add any sticky items that aren't already rendered\n const missingStickyIndices: { id: string; index: number }[] = [];\n for (const id of stickyIds) {\n if (renderedIds.has(id)) continue;\n // The drag knows its item's index; the index map serves the other sticky items\n const index =\n id === draggedId ? this.#draggedItemIndex() : (this.#itemIndexMap().get(id) ?? -1);\n if (index < 0) continue;\n missingStickyIndices.push({ id, index });\n }\n if (missingStickyIndices.length > 1) {\n missingStickyIndices.sort((a, b) => a.index - b.index);\n }\n\n for (const { id, index } of missingStickyIndices) {\n const item = items[index];\n if (item === undefined) continue;\n result.push({\n type: 'item',\n data: item,\n index,\n isSticky: true,\n isDragging: id === draggedId,\n });\n }\n\n return result;\n });\n\n /** Track keys of #renderedRows, in order */\n readonly #rowKeys = computed(() =>\n this.#renderedRows().map((entry, i) => this.trackEntry(i, entry)),\n );\n\n /**\n * Where the placeholder renders among the rows: before the row at this position (after the\n * rows in range when it equals their count), or -1 when it is not rendered. It goes before the\n * item at the placeholder index when that item is in range, and after the rows in range when\n * the index is past the last item.\n */\n readonly #placeholderSlot = computed(() => {\n const placeholderIndex = this.placeholderIndex();\n if (placeholderIndex < 0) return -1;\n\n const itemCount = this.items().length;\n const { start, end } = this.#renderRange();\n const lastInRange = Math.min(end, itemCount - 1);\n if (placeholderIndex >= start && placeholderIndex <= lastInRange) {\n return placeholderIndex - start;\n }\n if (placeholderIndex >= itemCount) {\n return Math.max(0, lastInRange - start + 1);\n }\n return -1;\n });\n\n /** Items to render, including sticky items and placeholder */\n protected readonly renderedItems = computed(() => {\n const rows = this.#renderedRows();\n const slot = this.#placeholderSlot();\n\n const result: {\n type: 'item' | 'placeholder';\n data: T | null;\n index: number;\n isSticky: boolean;\n // The container doesn't read it, but subclasses can: renderedItems is protected\n isDragging: boolean;\n }[] = [...rows];\n if (slot >= 0) {\n result.splice(slot, 0, {\n type: 'placeholder',\n data: null,\n index: this.placeholderIndex(),\n isSticky: false,\n isDragging: false,\n });\n }\n return result;\n });\n\n /** Generated ID for auto-scroll registration */\n #generatedScrollId = `vdnd-scroll-${Math.random().toString(36).slice(2, 9)}`;\n\n /** Track previous dragged ID to detect drag end */\n #previousDraggedId: string | null = null;\n\n /** Track previous total height to detect if we were at bottom before drag ended */\n #previousTotalHeight = 0;\n\n constructor() {\n createAutoScrollRegistration({\n autoScrollService: this.#autoScrollService,\n getElement: () => this.#elementRef.nativeElement,\n getId: () => this.scrollContainerId() ?? this.#generatedScrollId,\n enabled: () => this.autoScrollEnabled(),\n config: () => this.autoScrollConfig(),\n });\n\n // Keep the strategy's items in sync. A fixed-height strategy needs only their count, which\n // spares computing every item's ID on each items change (each drop).\n effect(() => {\n setStrategyItems(this.#strategy(), this.items().length, () => this.#itemIds());\n });\n\n // Register strategy with drag index calculator for accurate drag calculations\n effect((onCleanup) => {\n const droppableId = this.droppableId();\n const strategy = this.#strategy();\n if (droppableId) {\n this.#dragIndexCalculator.registerStrategy(droppableId, strategy);\n onCleanup(() => this.#dragIndexCalculator.unregisterStrategy(droppableId));\n }\n });\n\n // Set excluded index persistently during same-list drag.\n effect(() => {\n const strategy = this.#strategy();\n const draggedIndex = this.#draggedItemIndex();\n strategy.setExcludedIndex(draggedIndex >= 0 ? draggedIndex : null);\n });\n\n // Keyboard drag autoscroll: keep the placeholder visible. Arrow keys call\n // #revealPlaceholder synchronously (through KeyboardDragService) so a drop right after a\n // move never lands outside the rendered range; this effect re-runs it when item\n // measurements or the viewport height change during the drag.\n effect((onCleanup) => {\n const droppableId = this.droppableId();\n if (!droppableId) return;\n const reveal = (): void => untracked(() => this.#revealPlaceholder());\n this.#keyboardDrag.registerRevealer(droppableId, reveal);\n onCleanup(() => this.#keyboardDrag.unregisterRevealer(droppableId, reveal));\n });\n effect(() => this.#revealPlaceholder());\n\n // Preserve scroll position when drag ends at bottom of list.\n // Safety net: totalHeight no longer shrinks during drag (getTotalHeight\n // ignores exclusion), but this logic remains as harmless protection\n // in case future changes reintroduce height variance.\n effect(() => {\n const currentDraggedId = this.draggedItemId();\n const currentTotalHeight = this.totalHeight();\n const element = this.#elementRef.nativeElement;\n\n // Detect drag end (was dragging, now not)\n if (this.#previousDraggedId !== null && currentDraggedId === null) {\n const currentScrollTop = element.scrollTop;\n const strategy = this.#strategy();\n strategy.version();\n const height = this.effectiveHeight();\n const totalItems = this.items().length;\n\n // Calculate if we were at/near bottom (within 10px tolerance)\n // using the height FROM THE PREVIOUS CYCLE (when dragging was active)\n const dragReducedMaxScroll = Math.max(0, this.#previousTotalHeight - height);\n const wasAtBottom = currentScrollTop >= dragReducedMaxScroll - 10;\n\n if (wasAtBottom && dragReducedMaxScroll > 0) {\n // Clear exclusion before calculating new height\n strategy.setExcludedIndex(null);\n\n // Adjust scroll to new bottom position after totalHeight increases\n afterNextRender(\n () => {\n const newTotalHeight = strategy.getTotalHeight(totalItems);\n const newMaxScroll = Math.max(0, newTotalHeight - height);\n element.scrollTop = newMaxScroll;\n this.#scrollTop.set(newMaxScroll);\n },\n { injector: this.#injector },\n );\n }\n }\n\n this.#previousDraggedId = currentDraggedId;\n this.#previousTotalHeight = currentTotalHeight;\n });\n\n // Clamp scrollTop during drag if totalHeight ever shrinks.\n // With the current fix, getTotalHeight no longer excludes the dragged item,\n // so this is effectively a no-op. Kept as a safety net.\n effect(() => {\n const isDragging = this.#dragState.isDragging();\n const totalHeight = this.totalHeight();\n const element = this.#elementRef.nativeElement;\n\n if (isDragging) {\n const containerHeight = this.effectiveHeight();\n const maxScroll = Math.max(0, totalHeight - containerHeight);\n const currentScrollTop = element.scrollTop;\n\n // Clamp scrollTop to valid range\n if (currentScrollTop > maxScroll) {\n element.scrollTop = maxScroll;\n this.#scrollTop.set(maxScroll);\n }\n }\n });\n\n effect(() => {\n const spacer = this.spacer()?.nativeElement;\n if (spacer) {\n spacer.style.height = `${this.totalHeight()}px`;\n }\n });\n\n // Last, so it renders what the effects above scrolled to. Component effects run before the\n // component's own view is checked, which has nothing to update: the template has no bindings.\n effect(() => this.#render());\n }\n\n ngOnChanges(): void {\n this.#viewCheckPending = true;\n }\n\n ngOnInit(): void {\n // Measure rows in dynamic height mode. dynamicItemHeight can change at runtime, and the\n // strategy is replaced when it (or itemHeight) does, so this creates, replaces or removes the\n // observer. #observeRenderedItems observes every rendered row with each new observer, so a\n // new strategy gets their heights.\n effect(\n (onCleanup) => {\n // No ResizeObserver during server rendering\n if (!this.dynamicItemHeight() || !this.#isBrowser) return;\n this.#strategy();\n const observer = untracked(() => this.#createItemResizeObserver());\n this.#itemResizeObserver.set(observer);\n onCleanup(() => {\n observer.disconnect();\n this.#observedElementByKey.clear();\n this.#itemResizeObserver.set(null);\n });\n },\n { injector: this.#injector },\n );\n }\n\n ngAfterViewInit(): void {\n const element = this.#elementRef.nativeElement;\n\n this.#resizeCleanup = bindResizeObserverHeightSignal({\n element,\n ngZone: this.#ngZone,\n height: this.#measuredHeight,\n minDeltaPx: 1,\n });\n\n // Scroll listener outside Angular zone with RAF throttling.\n // This avoids template event binding which would mark the component dirty 60x/sec.\n this.#scrollCleanup = bindRafThrottledScrollTopSignal({\n element,\n ngZone: this.#ngZone,\n scrollTop: this.#scrollTop,\n thresholdPx: 5,\n });\n\n // Observe rendered items for dynamic height measurement\n this.#observeRenderedItems();\n }\n\n ngAfterViewChecked(): void {\n this.#viewCheckPending = false;\n }\n\n /**\n * Scroll so the placeholder is fully visible during a keyboard drag into this list.\n * Reads only signals and strategy offsets, so it works before the placeholder renders.\n */\n #revealPlaceholder(): void {\n // Only apply when this droppable is active during keyboard drag\n if (!this.#dragState.isKeyboardDrag()) return;\n const activeDroppable = this.#dragState.activeDroppableId();\n if (activeDroppable !== this.droppableId()) return;\n\n // The placeholder renders before the item at placeholderIndex. Below the source in the\n // same list that is keyboardTargetIndex + 1: the dragged item's slot is excluded.\n if (this.#dragState.keyboardTargetIndex() === null) return;\n const placeholderIndex = this.placeholderIndex();\n if (placeholderIndex < 0) return;\n\n const strategy = this.#strategy();\n strategy.version();\n const height = this.effectiveHeight();\n if (height <= 0) return;\n\n const element = this.#elementRef.nativeElement;\n const currentScrollTop = element.scrollTop;\n\n // Calculate placeholder position using strategy\n const targetTop = strategy.getOffsetForIndex(placeholderIndex);\n const targetBottom = targetTop + this.placeholderHeight();\n\n // Calculate visible range\n const viewportTop = currentScrollTop;\n const viewportBottom = currentScrollTop + height;\n\n // Check if target is fully visible\n if (targetTop < viewportTop) {\n // Target is above viewport - scroll up\n element.scrollTop = targetTop;\n this.#scrollTop.set(targetTop);\n } else if (targetBottom > viewportBottom) {\n // Target is below viewport - scroll down\n const newScrollTop = targetBottom - height;\n element.scrollTop = newScrollTop;\n this.#scrollTop.set(newScrollTop);\n }\n }\n\n /**\n * Render the content offset, the rows and the placeholder. From an effect, not the template:\n * Angular checks every row view in this component's view each time a signal its template reads\n * changes, so reading the placeholder there re-rendered every row on each placeholder move.\n * Here a placeholder move only moves the placeholder, and a row renders when its context does.\n */\n #render(): void {\n // Snapshot the rendered positions before anything moves, so displaced rows can slide. First,\n // as a subclass that renders its own template relies on it too.\n const isDragging = this.#dragState.isDragging();\n const placeholderIndex = this.placeholderIndex();\n untracked(() => this.#shiftAnimator?.beforeUpdate(isDragging, placeholderIndex));\n\n const outlet = this.rowOutlet();\n const wrapper = this.contentWrapper()?.nativeElement;\n // Not this component's template (a subclass's own): it renders renderedItems() itself\n if (!outlet || !wrapper) return;\n\n const template = this.itemTemplate() ?? null;\n const entries = this.#renderedRows();\n const keys = this.#rowKeys();\n const trackBy = this.effectiveTrackByFn();\n const recycle = this.recycleRows();\n const transform = this.contentTransform();\n const slot = this.#placeholderSlot();\n const placeholderHeight = slot >= 0 ? this.placeholderHeight() : null;\n\n // Untracked: the signals the rows' templates read must not become this effect's\n untracked(() => {\n if (transform !== this.#contentTransformSet) {\n wrapper.style.transform = transform;\n this.#contentTransformSet = transform;\n }\n this.#renderRows(outlet, template, entries, keys, trackBy, recycle);\n this.#renderPlaceholder(outlet, slot, placeholderHeight);\n });\n }\n\n /**\n * Give each entry a view of the item template, in order. As with `@for`, a row keeps its view\n * (and the components in it) while its track key stays rendered, and only the rows out of order\n * move. The view of a row that leaves is destroyed, or with `recycle` pooled and given to a row\n * that comes in. Only new, pooled and changed views are checked, with `detectChanges()`:\n * `markForCheck()` would mark every ancestor view up to the root too.\n */\n #renderRows(\n outlet: ViewContainerRef,\n template: TemplateRef<VirtualScrollItemContext<T>> | null,\n entries: RenderedEntry<T>[],\n keys: unknown[],\n trackBy: unknown,\n recycle: boolean,\n ): void {\n if (!recycle) {\n this.#destroyRowPool();\n }\n\n // Nothing to do, as on a placeholder move\n if (\n entries === this.#rowEntries &&\n template === this.#rowTemplate &&\n trackBy === this.#rowTrackBy\n ) {\n return;\n }\n\n // A new template renders every row anew; without one there is no row (as ngTemplateOutlet)\n if (template !== this.#rowTemplate) {\n for (const row of this.#rows) {\n row.view.destroy();\n }\n this.#rows = [];\n this.#destroyRowPool();\n this.#rowTemplate = template;\n }\n if (!template) return;\n\n // A new track function gives the rendered rows new keys; they keep their views (as with @for)\n if (trackBy !== this.#rowTrackBy) {\n for (const row of this.#rows) {\n const { $implicit, index } = row.view.context;\n row.key = this.trackEntry(index, { type: 'item', data: $implicit, index });\n }\n this.#rowTrackBy = trackBy;\n }\n\n // The last render's views by key, in order: an entry takes the first view left for its key\n const previous = new Map<unknown, RowView<T>[]>();\n for (const row of this.#rows) {\n if (row.view.destroyed) continue;\n const views = previous.get(row.key);\n if (views) {\n views.push(row);\n } else {\n previous.set(row.key, [row]);\n }\n }\n const kept = keys.map((key) => previous.get(key)?.shift());\n this.#warnDuplicateKeys(keys);\n\n // Remove the rows that left, then keep in place the longest run of kept views that is\n // already in order (their positions in the outlet, which now holds only kept views)\n const dragged = this.#dragState.draggedItem();\n for (const views of previous.values()) {\n for (const row of views) {\n // The dragged item's view is destroyed, as without recycling: that cancels the drag\n // instead of handing it to another item\n if (recycle && !this.#rendersDraggedItem(row.view, dragged)) {\n this.#poolRow(outlet, row.view);\n } else {\n row.view.destroy();\n }\n }\n }\n const positions = new Map<unknown, number>();\n for (let i = 0; i < outlet.length; i++) {\n positions.set(outlet.get(i), i);\n }\n const inPlace = longestIncreasingRun(kept.map((row) => (row ? positions.get(row.view)! : -1)));\n\n // From the last row up, so each row goes right before the next one, already in place\n const rows: RowView<T>[] = new Array(entries.length);\n const toCheck: EmbeddedViewRef<VirtualScrollItemContext<T>>[] = [];\n let next: EmbeddedViewRef<VirtualScrollItemContext<T>> | null = null;\n for (let i = entries.length - 1; i >= 0; i--) {\n const entry = entries[i];\n let row = kept[i];\n if (row) {\n if (!inPlace[i]) {\n this.#moveBefore(outlet, row.view, next);\n }\n if (this.#updateContext(row.view.context, entry)) {\n toCheck.push(row.view);\n }\n } else {\n const index: number = next ? outlet.indexOf(next) : outlet.length;\n // A pooled view is checked whatever its context: nothing checked it while detached\n let view = this.#rowPool.pop();\n if (view) {\n this.#updateContext(view.context, entry);\n outlet.insert(view, index);\n } else {\n const context: VirtualScrollItemContext<T> = {\n $implicit: entry.data as T,\n index: entry.index,\n isSticky: entry.isSticky,\n };\n view = outlet.createEmbeddedView(template, context, index);\n }\n row = { key: keys[i], view };\n toCheck.push(view);\n }\n rows[i] = row;\n next = row.view;\n }\n this.#rows = rows;\n while (this.#rowPool.length > MAX_POOLED_ROWS) {\n this.#rowPool.pop()!.destroy();\n }\n\n // When this component's own view is checked later in this pass, that check renders every row\n if (!this.#viewCheckPending) {\n // Top to bottom (toCheck lists them bottom up)\n for (let i = toCheck.length - 1; i >= 0; i--) {\n toCheck[i].detectChanges();\n }\n }\n this.#rowEntries = entries;\n }\n\n /**\n * Whether a row's view renders the dragged item: its item has the dragged ID, or the view holds\n * the dragged element (its draggable ID need not be the item's ID).\n */\n #rendersDraggedItem(\n view: EmbeddedViewRef<VirtualScrollItemContext<T>>,\n dragged: DraggedItem | null,\n ): boolean {\n if (!dragged) return false;\n return (\n this.itemIdFn()(view.context.$implicit) === dragged.draggableId ||\n view.rootNodes.some((node: Node) => node.contains(dragged.element))\n );\n }\n\n /**\n * Take a row's view out of the outlet and pool it. It keeps its element, so its shift\n * animation is cancelled (the item it renders next must not slide from this one's position),\n * and a drop animation that hides it shows it again.\n */\n #poolRow(outlet: ViewContainerRef, view: EmbeddedViewRef<VirtualScrollItemContext<T>>): void {\n outlet.detach(outlet.indexOf(view));\n const nodes = view.rootNodes;\n // A leave animation (`animate.leave`) keeps the row in the DOM, and Angular removes it when\n // the animation ends: in the row of another item by then, if the view were reused\n if (nodes.some((node) => node.parentNode !== null)) {\n view.destroy();\n return;\n }\n for (const node of nodes) {\n if (node instanceof HTMLElement) {\n this.#shiftAnimator?.cancel(node);\n }\n }\n revealDropTargetIn(nodes);\n this.#rowPool.push(view);\n }\n\n #destroyRowPool(): void {\n for (const view of this.#rowPool) {\n view.destroy();\n }\n this.#rowPool = [];\n }\n\n /** Move a row's view right before `next` (last without one), unless it is there already. */\n #moveBefore(\n outlet: ViewContainerRef,\n view: EmbeddedViewRef<VirtualScrollItemContext<T>>,\n next: EmbeddedViewRef<VirtualScrollItemContext<T>> | null,\n ): void {\n const target = next ? outlet.indexOf(next) : outlet.length;\n const current = outlet.indexOf(view);\n if (current === target - 1) return;\n // move() takes the view out before inserting it, which shifts the views after it\n outlet.move(view, current < target ? target - 1 : target);\n }\n\n /** Copy an entry into a row's context. Returns whether the context changed. */\n #updateContext(context: VirtualScrollItemContext<T>, entry: RenderedEntry<T>): boolean {\n if (\n Object.is(context.$implicit, entry.data) &&\n context.index === entry.index &&\n context.isSticky === entry.isSticky\n ) {\n return false;\n }\n context.$implicit = entry.data as T;\n context.index = entry.index;\n context.isSticky = entry.isSticky;\n return true;\n }\n\n /** Items sharing a track key still render (a view each), but drag and drop needs unique IDs. */\n #warnDuplicateKeys(keys: unknown[]): void {\n if (this.#warnedDuplicateKeys || keys === this.#rowKeysChecked || !isDevMode()) return;\n this.#rowKeysChecked = keys;\n const seen = new Set<unknown>();\n for (const key of keys) {\n if (seen.has(key)) {\n this.#warnedDuplicateKeys = true;\n console.warn(\n `[ngx-virtual-dnd] vdnd-virtual-scroll rendered two items with the track key ` +\n `${String(key)}. Give every item a unique ID (itemIdFn, or trackByFn).`,\n );\n return;\n }\n seen.add(key);\n }\n }\n\n /**\n * Put the placeholder before the row at `slot` (see #placeholderSlot), or take it out of the\n * DOM. It is a DragPlaceholderComponent of its own, outside this view: moving it or setting its\n * height checks no row.\n */\n #renderPlaceholder(outlet: ViewContainerRef, slot: number, height: number | null): void {\n if (slot < 0 || height === null) {\n this.#placeholderElement()?.remove();\n return;\n }\n\n this.#placeholder ??= createComponent(DragPlaceholderComponent, {\n environmentInjector: this.#environmentInjector,\n });\n if (height !== this.#placeholderHeightSet) {\n this.#placeholder.setInput('itemHeight', height);\n this.#placeholder.changeDetectorRef.detectChanges();\n this.#placeholderHeightSet = height;\n }\n\n // Rows are inserted before the outlet's anchor, so the anchor follows the last of them\n const anchor: Node = outlet.element.nativeElement;\n const parent = anchor.parentNode;\n const element = this.#placeholderElement();\n if (!parent || !element) return;\n const before = this.#firstNodeOfRows(slot, parent) ?? anchor;\n if (element.nextSibling !== before) {\n parent.insertBefore(element, before);\n }\n }\n\n #placeholderElement(): HTMLElement | null {\n return this.#placeholder?.location.nativeElement ?? null;\n }\n\n /** The first node in `parent` of the rows from `index` on (null when none has one). */\n #firstNodeOfRows(index: number, parent: Node): Node | null {\n for (let i = index; i < this.#rows.length; i++) {\n const nodes = this.#rows[i].view.rootNodes.filter((node) => node.parentNode === parent);\n const node = firstInDocumentOrder(nodes);\n if (node) return node;\n }\n return null;\n }\n\n ngOnDestroy(): void {\n this.#scrollCleanup?.();\n this.#resizeCleanup?.();\n const itemResizeObserver = this.#itemResizeObserver();\n for (const element of this.#observedElementByKey.values()) {\n itemResizeObserver?.unobserve(element);\n }\n this.#observedElementByKey.clear();\n itemResizeObserver?.disconnect();\n this.#shiftAnimator?.cancelAll();\n // Detached, so not destroyed with this view\n this.#destroyRowPool();\n // Created outside this view, so not destroyed with it (and destroy() leaves it in the DOM)\n this.#placeholderElement()?.remove();\n this.#placeholder?.destroy();\n this.#placeholder = null;\n }\n\n #createShiftAnimator(): ShiftAnimator | null {\n const config = inject(VDND_ANIMATION_CONFIG, { optional: true });\n if (!config) return null;\n return new ShiftAnimator({\n config,\n injector: this.#injector,\n getScrollElement: () => this.#elementRef.nativeElement,\n getEntries: () => this.#shiftAnimationEntries(),\n });\n }\n\n /**\n * Rendered item roots, keyed by the row's track key (a recycled view renders another item, so\n * its element is no identity), and the placeholder.\n */\n *#shiftAnimationEntries(): Iterable<ShiftAnimationEntry> {\n if (this.rowOutlet()) {\n for (const row of this.#rows) {\n for (const node of row.view.rootNodes) {\n if (node instanceof HTMLElement) {\n yield [row.key, node];\n }\n }\n }\n const placeholder = this.#placeholderElement();\n if (placeholder?.isConnected) {\n yield [placeholder, placeholder];\n }\n return;\n }\n\n // A subclass's own template (see #render) never recycles: each element is its own identity\n const wrapper = this.#elementRef.nativeElement.querySelector(\n '.vdnd-virtual-scroll-content-wrapper',\n );\n if (!wrapper) return;\n for (const child of Array.from(wrapper.children)) {\n if (child instanceof HTMLElement) {\n yield [child, child];\n }\n }\n }\n\n /**\n * Create the ResizeObserver that measures individual item heights.\n */\n #createItemResizeObserver(): ResizeObserver {\n return this.#ngZone.runOutsideAngular(\n () =>\n new ResizeObserver((entries) => {\n const strategy = this.#strategy();\n for (const entry of entries) {\n const element = entry.target as HTMLElement;\n const key = this.#observedElements.get(element);\n if (key === undefined) continue;\n\n const height = entry.borderBoxSize?.[0]?.blockSize ?? element.offsetHeight;\n if (height > 0) {\n strategy.setMeasuredHeight(key, height);\n }\n }\n }),\n );\n }\n\n /**\n * Observe currently rendered items' DOM elements for height changes.\n * Called after view init; re-observes after each render in dynamic mode, and every rendered\n * item when a new observer is created.\n */\n #observeRenderedItems(): void {\n // Re-observe whenever the rows change, once #render has put them in the DOM. The rows, not\n // renderedItems(): a placeholder move changes no row. A new item template changes no entry\n // but renders every row anew, as new elements.\n afterRenderEffect(\n () => {\n const observer = this.#itemResizeObserver();\n if (!observer) return;\n const rendered = this.#renderedRows();\n const idFn = this.itemIdFn();\n this.itemTemplate();\n\n // Find the content wrapper and observe item elements\n const wrapper = this.#elementRef.nativeElement.querySelector(\n '.vdnd-virtual-scroll-content-wrapper',\n );\n if (!wrapper) return;\n\n // The DOM element of each item, by its data-draggable-id: one query for all rows, where a\n // query per row scanned the wrapper once for each (quadratic in the rendered rows)\n const elementsById = mapByAttribute<HTMLElement>(wrapper, 'data-draggable-id');\n const nextObservedByKey = new Map<unknown, HTMLElement>();\n\n for (const entry of rendered) {\n if (entry.type !== 'item' || !entry.data) continue;\n const key = idFn(entry.data);\n const el = elementsById.get(key);\n if (el) {\n nextObservedByKey.set(key, el);\n }\n }\n\n for (const [key, oldElement] of this.#observedElementByKey) {\n const nextElement = nextObservedByKey.get(key);\n if (nextElement !== oldElement) {\n observer.unobserve(oldElement);\n }\n }\n\n for (const [key, nextElement] of nextObservedByKey) {\n const currentElement = this.#observedElementByKey.get(key);\n if (currentElement !== nextElement) {\n this.#observedElements.set(nextElement, key);\n observer.observe(nextElement);\n }\n }\n\n this.#observedElementByKey.clear();\n for (const [key, element] of nextObservedByKey) {\n this.#observedElementByKey.set(key, element);\n }\n },\n { injector: this.#injector },\n );\n }\n\n /**\n * Scroll to a specific position.\n */\n scrollTo(position: number): void {\n const element = this.#elementRef.nativeElement;\n element.scrollTop = position;\n // Store where the browser actually scrolled. It clamps to the scrollable range, and if that\n // leaves the element where it was, no scroll event arrives to correct an out-of-range value.\n this.#scrollTop.set(element.scrollTop);\n }\n\n /**\n * Scroll to a specific item index.\n */\n scrollToIndex(index: number): void {\n const strategy = this.#strategy();\n const position = strategy.getOffsetForIndex(index);\n this.scrollTo(position);\n }\n\n /**\n * Get the current scroll position.\n */\n getScrollTop(): number {\n return this.#scrollTop();\n }\n\n /**\n * Get the total scrollable height.\n */\n getScrollHeight(): number {\n return this.totalHeight();\n }\n\n /**\n * Scroll by a delta amount.\n */\n scrollBy(delta: number): void {\n const newPosition = Math.max(\n 0,\n Math.min(this.getScrollTop() + delta, this.getScrollHeight() - this.effectiveHeight()),\n );\n this.scrollTo(newPosition);\n }\n}\n","import {\n afterNextRender,\n afterRenderEffect,\n ChangeDetectionStrategy,\n Component,\n computed,\n effect,\n ElementRef,\n inject,\n Injector,\n input,\n OnDestroy,\n signal,\n TemplateRef,\n untracked,\n viewChild,\n} from '@angular/core';\nimport { NgTemplateOutlet } from '@angular/common';\nimport { DragStateService } from '../services/drag-state.service';\nimport { DragSchedulerService } from '../services/drag-scheduler.service';\nimport { OverlayContainerService } from '../services/overlay-container.service';\nimport { CursorPosition, DraggedItem, DragState, GrabOffset } from '../models/drag-drop.models';\nimport { VDND_ANIMATION_CONFIG } from '../tokens/animation-config.token';\nimport { DropAnimator, findDropTarget } from '../utils/drop-animator';\nimport { DroppableRegistryService } from '../services/droppable-registry.service';\n\n/**\n * Context provided to the drag preview template.\n */\nexport interface DragPreviewContext<T = unknown> {\n /** The data associated with the dragged item */\n $implicit: T;\n /** The draggable ID */\n draggableId: string;\n /** The source droppable ID */\n droppableId: string;\n}\n\n/** Everything the preview position depends on except the cursor, which moves every frame. */\ninterface Placement {\n /** The position while the preview settles after a drop; null while it follows the cursor */\n settled: CursorPosition | null;\n /** Offset from the cursor to the preview's top-left corner */\n offset: GrabOffset;\n lockAxis: 'x' | 'y' | null;\n initialPosition: CursorPosition | null;\n}\n\n/** A preview that outlives its drag while it glides into the drop position. */\ninterface SettlingPreview {\n item: DraggedItem;\n position: CursorPosition;\n}\n\n/**\n * Renders a preview of the dragged item that follows the cursor.\n *\n * The component automatically teleports itself into a body-level overlay container,\n * so it works correctly even inside ancestors with CSS `transform` (e.g. Ionic pages).\n * It can be placed anywhere in the component tree.\n *\n * When `VDND_ANIMATION_CONFIG` is provided, the preview stays up briefly after a drop or\n * cancel and glides into the item's final position.\n *\n * @example\n * ```html\n * <vdnd-drag-preview>\n * <ng-template let-data let-id=\"draggableId\">\n * <div class=\"drag-preview\">{{ data.name }}</div>\n * </ng-template>\n * </vdnd-drag-preview>\n * ```\n */\n@Component({\n selector: 'vdnd-drag-preview',\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [NgTemplateOutlet],\n template: `\n @if (isVisible()) {\n <div\n #preview\n class=\"vdnd-drag-preview\"\n [class.vdnd-drag-preview-dropping]=\"isSettling()\"\n [attr.data-testid]=\"isSettling() ? 'vdnd-drag-preview-dropping' : 'vdnd-drag-preview'\"\n [style.width.px]=\"dimensions().width\"\n [style.height.px]=\"dimensions().height\"\n >\n @if (previewTemplate()) {\n <ng-container *ngTemplateOutlet=\"previewTemplate()!; context: templateContext()\">\n </ng-container>\n } @else if (clonedElement()) {\n <div class=\"vdnd-drag-preview-clone\" #cloneContainer></div>\n } @else {\n <div class=\"vdnd-drag-preview-default\">\n {{ displayedItem()?.draggableId }}\n </div>\n }\n </div>\n }\n `,\n styles: `\n .vdnd-drag-preview {\n box-sizing: border-box;\n position: fixed;\n left: 0;\n top: 0;\n will-change: transform;\n pointer-events: none;\n z-index: 1000;\n }\n\n .vdnd-drag-preview-clone {\n width: 100%;\n height: 100%;\n overflow: hidden;\n }\n `,\n})\nexport class DragPreviewComponent<T = unknown> implements OnDestroy {\n protected readonly dragState = inject(DragStateService);\n readonly #overlayContainer = inject(OverlayContainerService);\n readonly #elementRef = inject(ElementRef<HTMLElement>);\n readonly #injector = inject(Injector);\n readonly #droppableRegistry = inject(DroppableRegistryService);\n readonly #scheduler = inject(DragSchedulerService);\n readonly #dropAnimator = this.#createDropAnimator();\n\n /** Optional custom template for the preview */\n previewTemplate = input<TemplateRef<DragPreviewContext<T>>>();\n\n /** Offset from cursor to preview (to avoid cursor being on top of preview) */\n cursorOffset = input<{ x: number; y: number }>({ x: 8, y: 8 });\n\n /** Reference to the clone container element (cannot use ES private with viewChild) */\n private readonly cloneContainer = viewChild<ElementRef<HTMLElement>>('cloneContainer');\n\n /** The rendered preview box (cannot use ES private with viewChild) */\n private readonly previewElement = viewChild<ElementRef<HTMLElement>>('preview');\n\n /** Set while the preview animates into the drop position after the drag ended */\n readonly #settling = signal<SettlingPreview | null>(null);\n\n /** Whether the drag was still active on the last state change (detects drag end) */\n #wasDragging = false;\n\n /** Whether the preview is playing the drop animation */\n protected readonly isSettling = computed(() => this.#settling() !== null);\n\n /** The item shown: the live dragged item, or the dropped one while it settles */\n protected readonly displayedItem = computed(\n () => this.dragState.draggedItem() ?? this.#settling()?.item ?? null,\n );\n\n /**\n * Where the preview goes, from everything but the cursor. The template and its effects never\n * read the cursor: a signal read there would schedule a full application render on every\n * pointer frame, and that render lands after the frame is painted (one frame late).\n */\n readonly #placement = computed((): Placement => {\n const settling = this.#settling();\n if (settling && !this.dragState.isDragging()) {\n return {\n settled: settling.position,\n offset: { x: 0, y: 0 },\n initialPosition: null,\n lockAxis: null,\n };\n }\n return this.#placementFor({\n grabOffset: this.dragState.grabOffset(),\n initialPosition: this.dragState.initialPosition(),\n lockAxis: this.dragState.lockAxis(),\n });\n });\n\n /**\n * Moves the preview inside the drag scheduler's frame, right after the hit-test wrote the\n * cursor (bound for stable add/remove). The render-time write in the constructor covers the\n * rest: the preview appearing, keyboard drags and the settle.\n */\n readonly #writeFramePosition = (): void => {\n const preview = this.previewElement()?.nativeElement;\n if (!preview || this.#settling() || !this.dragState.isDragging()) {\n return;\n }\n this.#place(preview, this.#placement(), this.dragState.cursorPosition());\n };\n\n /** Whether this preview's template registration is currently counted (kept balanced). */\n #templateRegistered = false;\n\n /** The cloned element from drag state (used when no custom template is provided) */\n protected readonly clonedElement = computed(() => {\n if (this.previewTemplate()) {\n return null; // Custom template takes precedence\n }\n return this.displayedItem()?.clonedElement ?? null;\n });\n\n constructor() {\n this.#scheduler.addFrameWriter(this.#writeFramePosition);\n\n // Teleport host element into the body-level overlay container after first render.\n // This escapes any ancestor CSS transforms that would break position: fixed.\n afterNextRender(() => {\n const container = this.#overlayContainer.getContainerElement();\n if (container) {\n container.appendChild(this.#elementRef.nativeElement);\n }\n });\n\n // Place the preview when it appears or anything but the cursor changes (drag start,\n // keyboard drags, the settle). The cursor is read untracked; pointer moves are written by\n // #writeFramePosition. Runs before the settle's afterNextRender reads the transform.\n afterRenderEffect({\n write: () => {\n const preview = this.previewElement()?.nativeElement;\n const placement = this.#placement();\n if (preview) {\n this.#place(preview, placement, untracked(this.dragState.cursorPosition));\n }\n },\n });\n\n // Publish whether this preview renders via a custom template so the drag\n // directives can skip the drag-start element clone when it won't be shown.\n effect(() => {\n const hasTemplate = !!this.previewTemplate();\n if (hasTemplate && !this.#templateRegistered) {\n this.#overlayContainer.setTemplatePreviewActive(true);\n this.#templateRegistered = true;\n } else if (!hasTemplate && this.#templateRegistered) {\n this.#overlayContainer.setTemplatePreviewActive(false);\n this.#templateRegistered = false;\n }\n });\n\n // Effect to insert the cloned element into the container\n effect(() => {\n const container = this.cloneContainer()?.nativeElement;\n const clone = this.clonedElement();\n\n if (!container) {\n return;\n }\n\n // Clear previous content and append the prepared clone element.\n // Avoid cloning again: ElementCloneService already creates a styled/sanitized clone.\n container.innerHTML = '';\n if (clone) {\n container.appendChild(clone);\n }\n });\n\n // Drop animation: when a drag ends, keep the preview up and glide it into place.\n // A new drag cuts any settle short.\n effect(() => {\n const isDragging = this.dragState.isDragging();\n untracked(() => {\n const wasDragging = this.#wasDragging;\n this.#wasDragging = isDragging;\n if (isDragging) {\n this.#stopSettling();\n } else if (wasDragging) {\n this.#startSettling();\n }\n });\n });\n }\n\n ngOnDestroy(): void {\n this.#scheduler.removeFrameWriter(this.#writeFramePosition);\n this.#dropAnimator?.cancel();\n if (this.#templateRegistered) {\n this.#overlayContainer.setTemplatePreviewActive(false);\n this.#templateRegistered = false;\n }\n this.#elementRef.nativeElement.remove();\n }\n\n /**\n * Whether the preview is visible. A drag shows it once it has a position: `initialPosition`\n * is set from the drag-start cursor and, unlike `cursorPosition`, does not change per frame.\n */\n protected readonly isVisible = computed(() => {\n return (\n (this.dragState.isDragging() && this.dragState.initialPosition() !== null) ||\n this.isSettling()\n );\n });\n\n #placementFor(state: Pick<DragState, 'grabOffset' | 'initialPosition' | 'lockAxis'>): Placement {\n return {\n settled: null,\n // Use grab offset if available (preserves grab position), otherwise fall back to cursorOffset input\n offset: state.grabOffset ?? this.cursorOffset(),\n initialPosition: state.initialPosition,\n lockAxis: state.lockAxis,\n };\n }\n\n #positionAt(placement: Placement, cursor: CursorPosition | null): CursorPosition {\n if (placement.settled) {\n return placement.settled;\n }\n if (!cursor) {\n return { x: 0, y: 0 };\n }\n\n const { offset, initialPosition, lockAxis } = placement;\n let x = cursor.x - offset.x;\n let y = cursor.y - offset.y;\n\n // Apply axis locking if configured\n if (lockAxis && initialPosition) {\n if (lockAxis === 'x') {\n // Lock X axis: x stays at initial position\n x = initialPosition.x - offset.x;\n } else if (lockAxis === 'y') {\n // Lock Y axis: y stays at initial position\n y = initialPosition.y - offset.y;\n }\n }\n\n return { x, y };\n }\n\n /** Transform-based positioning for better performance (avoid layout from left/top). */\n #place(preview: HTMLElement, placement: Placement, cursor: CursorPosition | null): void {\n const { x, y } = this.#positionAt(placement, cursor);\n preview.style.transform = `translate3d(${x}px, ${y}px, 0)`;\n }\n\n /** Dimensions of the preview */\n protected readonly dimensions = computed(() => {\n const item = this.displayedItem();\n\n if (!item) {\n return { width: 100, height: 50 };\n }\n\n return {\n width: item.width,\n height: item.height,\n };\n });\n\n /** Template context */\n protected readonly templateContext = computed((): DragPreviewContext<T> => {\n const item = this.displayedItem();\n\n return {\n $implicit: (item?.data ?? null) as T,\n draggableId: item?.draggableId ?? '',\n droppableId: item?.droppableId ?? '',\n };\n });\n\n #createDropAnimator(): DropAnimator | null {\n const config = inject(VDND_ANIMATION_CONFIG, { optional: true });\n return config ? new DropAnimator(config) : null;\n }\n\n /**\n * Keep the ended drag's preview on screen, then (once the consumer's drop handler has\n * re-rendered the lists) animate it onto the item's final position.\n */\n #startSettling(): void {\n const ended = this.dragState.endedDragState();\n if (!this.#dropAnimator?.isEnabled() || !ended?.draggedItem || !ended.cursorPosition) {\n return;\n }\n\n const settling: SettlingPreview = {\n item: ended.draggedItem,\n position: this.#positionAt(this.#placementFor(ended), ended.cursorPosition),\n };\n this.#settling.set(settling);\n\n // A normal drop lands in the target list; a cancel, a rejected drop or one the consumer\n // has not committed yet leaves the item in its source list.\n const droppableIds = this.dragState.wasCancelled()\n ? [ended.sourceDroppableId]\n : [ended.activeDroppableId, ended.sourceDroppableId];\n\n afterNextRender(\n () => {\n if (this.#settling() !== settling) {\n return;\n }\n const ghost = this.previewElement()?.nativeElement;\n if (!ghost || !this.#dropAnimator) {\n this.#settling.set(null);\n return;\n }\n const target = findDropTarget(settling.item.draggableId, droppableIds, (id) =>\n this.#droppableRegistry.getById(id),\n );\n this.#dropAnimator.play(ghost, target, () => {\n if (this.#settling() === settling) {\n this.#settling.set(null);\n }\n });\n },\n { injector: this.#injector },\n );\n }\n\n #stopSettling(): void {\n this.#dropAnimator?.cancel();\n this.#settling.set(null);\n }\n}\n","import { ChangeDetectionStrategy, Component, input, TemplateRef } from '@angular/core';\nimport { NgTemplateOutlet } from '@angular/common';\n\n/**\n * Context provided to the custom placeholder template.\n */\nexport interface PlaceholderContext {\n /** The height of the placeholder in pixels */\n $implicit: number;\n /** The height of the placeholder in pixels (explicit property) */\n height: number;\n}\n\n/**\n * A placeholder component that indicates where a dropped item will be inserted.\n *\n * By default, renders as empty/transparent space. Pass a custom template\n * to customize the placeholder appearance.\n *\n * @example\n * ```html\n * <!-- Default: transparent/empty space -->\n * <vdnd-placeholder [height]=\"50\"></vdnd-placeholder>\n *\n * <!-- Custom template with dashed border -->\n * <vdnd-placeholder [height]=\"50\" [template]=\"customPlaceholder\">\n * <ng-template #customPlaceholder let-height>\n * <div class=\"my-placeholder\" [style.height.px]=\"height\">\n * Drop here\n * </div>\n * </ng-template>\n * </vdnd-placeholder>\n * ```\n */\n@Component({\n selector: 'vdnd-placeholder',\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [NgTemplateOutlet],\n host: {\n class: 'vdnd-placeholder',\n '[style.height.px]': 'height()',\n '[attr.data-draggable-id]': '\"placeholder\"',\n },\n template: `\n @if (template()) {\n <ng-container\n *ngTemplateOutlet=\"template()!; context: { $implicit: height(), height: height() }\"\n >\n </ng-container>\n }\n `,\n styles: `\n :host {\n display: block;\n box-sizing: border-box;\n }\n `,\n})\nexport class PlaceholderComponent {\n /** Height of the placeholder in pixels */\n height = input<number>(50);\n\n /** Optional custom template for the placeholder content */\n template = input<TemplateRef<PlaceholderContext>>();\n}\n","import { Directive, InjectionToken, input, Signal } from '@angular/core';\n\n/**\n * Token for injecting the group context from a parent directive.\n * Allows child draggables and droppables to inherit the group name automatically.\n */\nexport const VDND_GROUP_TOKEN = new InjectionToken<VdndGroupContext>('VDND_GROUP_TOKEN');\n\n/**\n * Context provided by the group directive to its children.\n */\nexport interface VdndGroupContext {\n /** The group name signal */\n readonly group: Signal<string>;\n}\n\n/**\n * Provides a group context to child draggable and droppable directives.\n * When applied to a parent element, child directives can inherit the group name\n * automatically without needing to specify it on each element.\n *\n * @example\n * ```html\n * <!-- Without group directive (verbose) -->\n * <div vdndDroppable=\"list-1\" vdndDroppableGroup=\"my-group\">\n * <div vdndDraggable=\"item-1\" vdndDraggableGroup=\"my-group\">Item 1</div>\n * <div vdndDraggable=\"item-2\" vdndDraggableGroup=\"my-group\">Item 2</div>\n * </div>\n *\n * <!-- With group directive (concise) -->\n * <div vdndGroup=\"my-group\">\n * <div vdndDroppable=\"list-1\">\n * <div vdndDraggable=\"item-1\">Item 1</div>\n * <div vdndDraggable=\"item-2\">Item 2</div>\n * </div>\n * </div>\n * ```\n */\n@Directive({\n selector: '[vdndGroup]',\n providers: [\n {\n provide: VDND_GROUP_TOKEN,\n useExisting: DroppableGroupDirective,\n },\n ],\n})\nexport class DroppableGroupDirective implements VdndGroupContext {\n /** The group name that will be inherited by child directives */\n readonly group = input.required<string>({ alias: 'vdndGroup' });\n}\n","import { computed, isDevMode, type Signal } from '@angular/core';\nimport type { VdndGroupContext } from '../directives/droppable-group.directive';\n\n/**\n * Configuration options for creating an effective group signal.\n */\nexport interface GroupResolutionOptions {\n /** The explicit group input signal */\n explicitGroup: Signal<string | undefined>;\n /** The parent group context injected via VDND_GROUP_TOKEN (may be null) */\n parentGroup: VdndGroupContext | null;\n /** The element ID signal for warning messages */\n elementId: Signal<string>;\n /** The type of element ('draggable' or 'droppable') for warning messages */\n elementType: 'draggable' | 'droppable';\n}\n\n/**\n * State tracker for group resolution to avoid repeated warnings.\n */\ninterface GroupResolutionState {\n hasWarnedMissingGroup: boolean;\n}\n\n/**\n * Creates a computed signal that resolves the effective group name for a draggable or droppable.\n *\n * Resolution order:\n * 1. Explicit group input (vdndDraggableGroup or vdndDroppableGroup)\n * 2. Inherited group from parent vdndGroup directive\n * 3. null (with dev-mode warning)\n *\n * @example\n * ```typescript\n * readonly #effectiveGroup = createEffectiveGroupSignal({\n * explicitGroup: this.vdndDraggableGroup,\n * parentGroup: this.#parentGroup,\n * elementId: this.vdndDraggable,\n * elementType: 'draggable',\n * });\n * ```\n */\nexport function createEffectiveGroupSignal(options: GroupResolutionOptions): Signal<string | null> {\n const { explicitGroup, parentGroup, elementId, elementType } = options;\n\n // State object to track whether we've warned (mutable closure state)\n const state: GroupResolutionState = { hasWarnedMissingGroup: false };\n\n return computed((): string | null => {\n const explicit = explicitGroup();\n if (explicit) return explicit;\n\n const inherited = parentGroup?.group();\n if (inherited) return inherited;\n\n if (isDevMode() && !state.hasWarnedMissingGroup) {\n const directive = elementType === 'draggable' ? 'vdndDraggable' : 'vdndDroppable';\n const groupInput = elementType === 'draggable' ? 'vdndDraggableGroup' : 'vdndDroppableGroup';\n const action = elementType === 'draggable' ? 'Drag' : 'Dropping';\n\n console.warn(\n `[ngx-virtual-dnd] [${directive}=\"${elementId()}\"] requires a group. ` +\n `Either set ${groupInput} or wrap in a vdndGroup directive. ` +\n `${action} will be disabled for this element.`,\n );\n state.hasWarnedMissingGroup = true;\n }\n\n return null;\n });\n}\n","/**\n * Normalize a placeholder index into the final same-list insertion index.\n *\n * Same-list drags render a placeholder in a list with the source item hidden, so placeholder\n * indexes after the source include a +1 hidden-source adjustment. Drop consumers receive the\n * post-removal insertion index, which subtracts that adjustment.\n */\nexport function normalizeDropDestinationIndex(args: {\n sourceIndex: number;\n placeholderIndex: number;\n sourceDroppableId: string | null;\n activeDroppableId: string | null;\n}): number;\nexport function normalizeDropDestinationIndex(args: {\n sourceIndex: number;\n placeholderIndex: number | null;\n sourceDroppableId: string | null;\n activeDroppableId: string | null;\n}): number | null;\nexport function normalizeDropDestinationIndex({\n sourceIndex,\n placeholderIndex,\n sourceDroppableId,\n activeDroppableId,\n}: {\n sourceIndex: number;\n placeholderIndex: number | null;\n sourceDroppableId: string | null;\n activeDroppableId: string | null;\n}): number | null {\n if (placeholderIndex === null) {\n return null;\n }\n\n if (\n sourceDroppableId !== null &&\n sourceDroppableId === activeDroppableId &&\n sourceIndex < placeholderIndex\n ) {\n return placeholderIndex - 1;\n }\n\n return placeholderIndex;\n}\n","import {\n afterNextRender,\n computed,\n Directive,\n effect,\n ElementRef,\n inject,\n input,\n NgZone,\n OnDestroy,\n output,\n untracked,\n} from '@angular/core';\nimport { DragStateService } from '../services/drag-state.service';\nimport { AutoScrollConfig, AutoScrollService } from '../services/auto-scroll.service';\nimport { DroppableRegistryService } from '../services/droppable-registry.service';\nimport {\n DraggedItem,\n DragState,\n DropEvent,\n END_OF_LIST,\n PlaceholderMoveEvent,\n} from '../models/drag-drop.models';\nimport { VDND_GROUP_TOKEN } from './droppable-group.directive';\nimport { createEffectiveGroupSignal } from '../utils/group-resolution';\nimport { createAutoScrollRegistration } from '../utils/auto-scroll-registration';\nimport { normalizeDropDestinationIndex } from '../utils/drop-index-normalization';\n\n/**\n * Marks an element as a valid drop target within the virtual scroll drag-and-drop system.\n *\n * @example\n * ```html\n * <!-- With explicit group -->\n * <div\n * vdndDroppable=\"list-1\"\n * vdndDroppableGroup=\"my-group\"\n * (drop)=\"onDrop($event)\">\n * <!-- Draggable items here -->\n * </div>\n *\n * <!-- With inherited group from parent vdndGroup directive -->\n * <div vdndGroup=\"my-group\">\n * <div vdndDroppable=\"list-1\" (drop)=\"onDrop($event)\">\n * <!-- Draggable items here -->\n * </div>\n * </div>\n * ```\n */\n@Directive({\n selector: '[vdndDroppable]',\n host: {\n '[attr.data-droppable-id]': 'vdndDroppable()',\n '[attr.data-droppable-group]': 'effectiveGroup()',\n '[attr.data-droppable-disabled]': 'disabled() || null',\n '[attr.data-constrain-to-container]': 'constrainToContainer() || null',\n '[attr.aria-dropeffect]': '\"move\"',\n '[class.vdnd-droppable]': 'true',\n '[class.vdnd-droppable-active]': 'isActive()',\n '[class.vdnd-droppable-disabled]': 'disabled()',\n },\n})\nexport class DroppableDirective implements OnDestroy {\n readonly #elementRef = inject(ElementRef<HTMLElement>);\n readonly #dragState = inject(DragStateService);\n readonly #autoScroll = inject(AutoScrollService);\n readonly #registry = inject(DroppableRegistryService);\n readonly #ngZone = inject(NgZone);\n readonly #parentGroup = inject(VDND_GROUP_TOKEN, { optional: true });\n\n /** Unique identifier for this droppable */\n vdndDroppable = input.required<string>();\n\n /**\n * Drag-and-drop group name.\n * Optional when a parent `vdndGroup` directive provides the group context.\n */\n vdndDroppableGroup = input<string>();\n\n /**\n * Resolved group name - uses explicit input or falls back to parent group.\n * Returns null (and disables dropping) if neither is available.\n */\n readonly effectiveGroup = createEffectiveGroupSignal({\n explicitGroup: this.vdndDroppableGroup,\n parentGroup: this.#parentGroup,\n elementId: this.vdndDroppable,\n elementType: 'droppable',\n });\n\n /** Optional data associated with this droppable */\n vdndDroppableData = input<unknown>();\n\n /** Whether this droppable is disabled */\n disabled = input<boolean>(false);\n\n /** Enable auto-scroll when dragging near edges */\n autoScrollEnabled = input<boolean>(true);\n\n /** Auto-scroll configuration */\n autoScrollConfig = input<Partial<AutoScrollConfig>>({});\n\n /** Constrain drag preview and placeholder to container boundaries */\n constrainToContainer = input<boolean>(false);\n\n /** Emits when an item is dropped on this droppable: at release, right after its `dragEnd` */\n // eslint-disable-next-line @angular-eslint/no-output-native\n drop = output<DropEvent>();\n\n /**\n * Emits each time the placeholder moves within this droppable during a drag\n * (every item displacement) — e.g. to trigger haptic feedback.\n */\n placeholderMove = output<PlaceholderMoveEvent>();\n\n /** Whether this droppable is currently being targeted */\n readonly isActive = computed(() => {\n const activeId = this.#dragState.activeDroppableId();\n return activeId === this.vdndDroppable() && !this.disabled();\n });\n\n /**\n * `END_OF_LIST` while this droppable is active, otherwise null.\n * @deprecated It never identifies an item. For the position, use the `placeholderMove` output\n * (and `DropEvent.destination.index` on drop). Will be removed in the next major version.\n */\n readonly placeholderId = computed(() => {\n if (!this.isActive()) {\n return null;\n }\n return this.#dragState.placeholderId();\n });\n\n /**\n * The placeholder's insertion index in this droppable (DropEvent convention),\n * or null when the placeholder is not here.\n */\n readonly #placeholderInsertionIndex = computed(() => {\n if (!this.isActive() || !this.#dragState.isDragging()) {\n return null;\n }\n const sourceIndex = this.#dragState.sourceIndex();\n return normalizeDropDestinationIndex({\n sourceIndex: sourceIndex ?? -1,\n placeholderIndex: this.#dragState.placeholderIndex(),\n // Without a known source index there is no hidden-source adjustment to undo\n sourceDroppableId: sourceIndex === null ? null : this.#dragState.sourceDroppableId(),\n activeDroppableId: this.vdndDroppable(),\n });\n });\n\n /** Last insertion index reported via placeholderMove (null when not here) */\n #lastPlaceholderIndex: number | null = null;\n\n /** Drag whose initial placeholder position has already been seen by this droppable */\n #placeholderTrackedDrag: DraggedItem | null = null;\n\n /** Whether this droppable has rendered, so its inputs have values */\n #rendered = false;\n\n constructor() {\n createAutoScrollRegistration({\n autoScrollService: this.#autoScroll,\n getElement: () => this.#elementRef.nativeElement,\n getId: () => this.vdndDroppable(),\n enabled: () => this.autoScrollEnabled(),\n config: () => this.autoScrollConfig(),\n // Register whenever a group is resolved; do NOT gate on scrollability. DOM size is\n // not reactive, so a list that becomes scrollable after init (async data, resize)\n // would never register. AutoScrollService filters by live scroll geometry per drag.\n canRegister: () => Boolean(this.effectiveGroup()),\n });\n\n afterNextRender(() => (this.#rendered = true));\n\n // Register with the droppable registry, and again under the new key when the ID or group\n // changes. Drag code finds drop targets through the registry instead of querying the\n // document; a registration during an active drag makes this droppable a target from the\n // next hit-test. The registry also calls #handleDrop when a drag ends on this droppable.\n // The cleanup unregisters it, including on destroy.\n //\n // Not deferred to afterNextRender: this runs in the change detection that creates the\n // droppable (inputs are set by then), so afterNextRender hooks of that same render (drop\n // animation, keyboard focus restore) already find it, and so does a view refreshed only\n // by its own detectChanges(). Nothing reads the registry before change detection ends.\n effect((onCleanup) => {\n const group = this.effectiveGroup();\n if (!group) {\n return;\n }\n onCleanup(\n this.#registry.register(\n this.#elementRef.nativeElement,\n this.vdndDroppable(),\n group,\n (endedState) => this.#handleDrop(endedState),\n ),\n );\n });\n\n effect(() => {\n const currentIndex = this.#placeholderInsertionIndex();\n untracked(() => this.#handlePlaceholderMove(currentIndex));\n });\n }\n\n ngOnDestroy(): void {\n // Destroyed before it rendered: its inputs may have no values yet and it never became the\n // active drop target. (Not an ngOnInit flag: a subclass with its own ngOnInit would skip\n // it.) A registry registration, if any, is removed by its effect's cleanup.\n if (!this.#rendered) {\n return;\n }\n\n // Clean up if this droppable is destroyed while being active\n if (this.isActive()) {\n this.#dragState.setActiveDroppable(null);\n }\n\n // Auto-scroll and the droppable registry unregister through their effects' cleanup.\n }\n\n /**\n * Emit placeholderMove when the placeholder moved within (or entered) this droppable.\n */\n #handlePlaceholderMove(currentIndex: number | null): void {\n let previousIndex = this.#lastPlaceholderIndex;\n this.#lastPlaceholderIndex = currentIndex;\n\n const draggedItem = this.#dragState.draggedItem();\n if (currentIndex === null || currentIndex === previousIndex || !draggedItem) {\n return;\n }\n\n // The drag's first placement in the source list starts from the item's own slot:\n // nothing is displaced when the placeholder simply takes the hidden item's place.\n const isFirstPlacement = this.#placeholderTrackedDrag !== draggedItem;\n this.#placeholderTrackedDrag = draggedItem;\n const sourceDroppableId = this.#dragState.sourceDroppableId();\n const sourceIndex = this.#dragState.sourceIndex();\n if (isFirstPlacement && sourceDroppableId === this.vdndDroppable() && sourceIndex !== null) {\n if (currentIndex === sourceIndex) {\n return;\n }\n previousIndex = sourceIndex;\n }\n\n this.placeholderMove.emit({\n draggableId: draggedItem.draggableId,\n sourceDroppableId: sourceDroppableId ?? '',\n droppableId: this.vdndDroppable(),\n previousIndex,\n currentIndex,\n data: draggedItem.data,\n });\n }\n\n /**\n * Emit `drop` for a drag that ended on this droppable. Called by the registry from\n * `DragStateService.endDrag()`, with the state captured just before the reset. Returns\n * whether it emitted.\n */\n #handleDrop(state: DragState): boolean {\n // A target disabled at release is not a valid drop (dragEnd reports no destination).\n if (this.disabled() || !state.draggedItem || state.activeDroppableId !== this.vdndDroppable()) {\n return false;\n }\n\n const sourceDroppableId = state.sourceDroppableId ?? '';\n const placeholderId = state.placeholderId ?? END_OF_LIST;\n\n // Use the stored source index from drag state\n // This is critical for virtual scrolling where the original element may no longer\n // be in the DOM after autoscroll (it gets virtualized out of view)\n const sourceIndex =\n state.sourceIndex ?? this.#getItemIndex(state.draggedItem.draggableId, sourceDroppableId);\n\n // Use the pre-calculated placeholderIndex if available (more reliable)\n // Fall back to DOM-based calculation if not. Then normalize to the same\n // consumer-facing insertion index emitted by DragEndEvent.\n const placeholderIndex =\n state.placeholderIndex !== null && state.placeholderIndex !== undefined\n ? state.placeholderIndex\n : this.#getDestinationIndex(placeholderId);\n const destinationIndex = normalizeDropDestinationIndex({\n sourceIndex,\n placeholderIndex,\n sourceDroppableId,\n activeDroppableId: this.vdndDroppable(),\n });\n\n const event: DropEvent = {\n source: {\n draggableId: state.draggedItem.draggableId,\n droppableId: sourceDroppableId,\n index: sourceIndex,\n data: state.draggedItem.data,\n },\n destination: {\n droppableId: this.vdndDroppable(),\n placeholderId,\n index: destinationIndex,\n data: this.vdndDroppableData(),\n },\n };\n // Delivered from the pointer/keyboard listener, which runs outside Angular's zone. With\n // zone.js a template listener marks its view dirty without scheduling a render, so emit\n // inside the zone for the consumer's handler (and async work it starts) to render. A\n // no-op when zoneless.\n this.#ngZone.run(() => this.drop.emit(event));\n return true;\n }\n\n /**\n * Get the index of an item in a droppable.\n * This is a simplified implementation - in practice, the consumer would track this.\n */\n #getItemIndex(draggableId: string, droppableId: string): number {\n // Find all draggables in the source droppable\n const droppable = this.#registry.getById(droppableId);\n if (!droppable) {\n return 0;\n }\n\n const draggables = droppable.querySelectorAll('[data-draggable-id]');\n for (let i = 0; i < draggables.length; i++) {\n if (draggables[i].getAttribute('data-draggable-id') === draggableId) {\n return i;\n }\n }\n\n return 0;\n }\n\n /**\n * Get the destination index based on the placeholder.\n */\n #getDestinationIndex(placeholderId: string): number {\n // Exclude placeholder elements from the count\n const draggables = this.#elementRef.nativeElement.querySelectorAll(\n '[data-draggable-id]:not([data-draggable-id=\"placeholder\"])',\n );\n\n if (placeholderId === END_OF_LIST) {\n return draggables.length;\n }\n\n // Find the index of the placeholder item\n for (let i = 0; i < draggables.length; i++) {\n if (draggables[i].getAttribute('data-draggable-id') === placeholderId) {\n return i;\n }\n }\n\n return 0;\n }\n\n /**\n * Get the element reference (for external use).\n */\n getElement(): HTMLElement {\n return this.#elementRef.nativeElement;\n }\n\n /**\n * Manually scroll this droppable.\n */\n scrollBy(delta: number): void {\n this.#elementRef.nativeElement.scrollTop += delta;\n }\n\n /**\n * Get the current scroll position.\n */\n getScrollTop(): number {\n return this.#elementRef.nativeElement.scrollTop;\n }\n\n /**\n * Get the scroll height.\n */\n getScrollHeight(): number {\n return this.#elementRef.nativeElement.scrollHeight;\n }\n}\n","import {\n ChangeDetectionStrategy,\n Component,\n Directive,\n inject,\n input,\n output,\n TemplateRef,\n} from '@angular/core';\nimport {\n VirtualScrollContainerComponent,\n VirtualScrollItemContext,\n} from './virtual-scroll-container.component';\nimport { DroppableDirective } from '../directives/droppable.directive';\nimport { AutoScrollConfig } from '../services/auto-scroll.service';\nimport { DropEvent, PlaceholderMoveEvent } from '../models/drag-drop.models';\n\n/**\n * Forwards the inner droppable's `drop` and `placeholderMove` to the sortable list's outputs.\n *\n * Not template listeners: Angular marks the listening view and every ancestor up to the root\n * dirty before running one, so each placeholder move would re-render the consumer's whole\n * component chain even when nothing listens to `placeholderMove`. A subscription marks nothing;\n * a consumer's own listener on the sortable list marks only its own view. Subscribed in the\n * constructor, before the droppable's first change detection can emit; both outputs drop their\n * listeners when the element is destroyed.\n */\n@Directive({ selector: '[vdndSortableListOutputs]' })\nclass SortableListOutputsDirective {\n constructor() {\n const droppable = inject(DroppableDirective);\n const list = inject(VirtualSortableListComponent);\n droppable.drop.subscribe((event) => list.drop.emit(event));\n droppable.placeholderMove.subscribe((event) => list.placeholderMove.emit(event));\n }\n}\n\n/**\n * A high-level component that combines droppable, virtual scroll, and placeholder\n * functionality into a single, easy-to-use component.\n *\n * This component significantly reduces boilerplate by automatically handling:\n * - Placeholder insertion at the correct position\n * - Sticky item management for the dragged item\n * - Virtual scrolling with proper drag-and-drop integration\n * - Droppable container setup\n *\n * @example\n * ```html\n * <!-- Before (verbose): ~45 lines of boilerplate -->\n * <div vdndDroppable=\"list-1\" vdndDroppableGroup=\"demo\" (drop)=\"onDrop($event)\">\n * <vdnd-virtual-scroll\n * [items]=\"itemsWithPlaceholder()\"\n * [itemHeight]=\"50\"\n * [stickyItemIds]=\"stickyIds()\"\n * [itemIdFn]=\"getItemId\"\n * [trackByFn]=\"trackById\"\n * [itemTemplate]=\"itemTpl\">\n * </vdnd-virtual-scroll>\n * </div>\n *\n * <!-- After (concise): ~8 lines -->\n * <div vdndGroup=\"demo\">\n * <vdnd-sortable-list\n * droppableId=\"list-1\"\n * [items]=\"list()\"\n * [itemHeight]=\"50\"\n * [itemIdFn]=\"getItemId\"\n * [itemTemplate]=\"itemTpl\"\n * (drop)=\"onDrop($event)\">\n * </vdnd-sortable-list>\n * </div>\n * ```\n */\n@Component({\n selector: 'vdnd-sortable-list',\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [VirtualScrollContainerComponent, DroppableDirective, SortableListOutputsDirective],\n host: {\n class: 'vdnd-sortable-list',\n },\n template: `\n <div\n class=\"vdnd-sortable-list-droppable\"\n [vdndDroppable]=\"droppableId()\"\n [vdndDroppableGroup]=\"group()\"\n [vdndDroppableData]=\"droppableData()\"\n [disabled]=\"disabled()\"\n [constrainToContainer]=\"constrainToContainer()\"\n vdndSortableListOutputs\n >\n <vdnd-virtual-scroll\n [items]=\"items()\"\n [itemHeight]=\"itemHeight()\"\n [dynamicItemHeight]=\"dynamicItemHeight()\"\n [itemIdFn]=\"itemIdFn()\"\n [trackByFn]=\"trackByFn()\"\n [itemTemplate]=\"itemTemplate()\"\n [droppableId]=\"droppableId()\"\n [autoStickyDraggedItem]=\"true\"\n [containerHeight]=\"containerHeight()\"\n [overscan]=\"overscan()\"\n [recycleRows]=\"recycleRows()\"\n [autoScrollEnabled]=\"autoScrollEnabled()\"\n [autoScrollConfig]=\"autoScrollConfig()\"\n >\n </vdnd-virtual-scroll>\n </div>\n `,\n styles: `\n :host {\n display: block;\n }\n `,\n})\nexport class VirtualSortableListComponent<T> {\n // ========== Required Inputs ==========\n\n /** Unique identifier for this droppable list */\n droppableId = input.required<string>();\n\n /**\n * Drag-and-drop group name.\n * Optional when a parent `vdndGroup` directive provides the group context.\n */\n group = input<string>();\n\n /** Array of items to render */\n items = input.required<T[]>();\n\n /** Height of each item in pixels (used as estimate in dynamic mode) */\n itemHeight = input.required<number>();\n\n /**\n * Enable dynamic item height mode.\n * When true, items are auto-measured via ResizeObserver and `itemHeight`\n * serves as the initial estimate for unmeasured items.\n */\n dynamicItemHeight = input<boolean>(false);\n\n /** Function to get a unique ID from an item */\n itemIdFn = input.required<(item: T) => string>();\n\n /** Template for rendering each item */\n itemTemplate = input.required<TemplateRef<VirtualScrollItemContext<T>>>();\n\n // ========== Optional Inputs ==========\n\n /**\n * Track-by function for the @for loop.\n * Optional - if not provided, will be derived from itemIdFn.\n */\n trackByFn = input<(index: number, item: T) => string | number>();\n\n /** Optional data associated with this droppable */\n droppableData = input<unknown>();\n\n /** Whether this sortable list is disabled */\n disabled = input<boolean>(false);\n\n /**\n * Height of the container in pixels.\n * If not provided, uses CSS-based height detection.\n */\n containerHeight = input<number>();\n\n /** Number of items to render above/below the visible area */\n overscan = input<number>(3);\n\n /**\n * Reuse the views of rows that scroll out to render the rows that scroll in, instead of\n * destroying them and creating new ones. Scrolling creates fewer components and elements, but\n * a row's components, element and DOM state (focus aside) then carry over to other items.\n * @default false\n */\n recycleRows = input<boolean>(false);\n\n /** Enable auto-scroll when dragging near edges */\n autoScrollEnabled = input<boolean>(true);\n\n /** Auto-scroll configuration */\n autoScrollConfig = input<Partial<AutoScrollConfig>>({});\n\n /** Constrain drag preview and placeholder to container boundaries */\n constrainToContainer = input<boolean>(false);\n\n // ========== Outputs ==========\n\n /** Emits when an item is dropped on this list */\n // eslint-disable-next-line @angular-eslint/no-output-native\n drop = output<DropEvent>();\n\n /** Emits each time the placeholder moves within this list (every item displacement) */\n placeholderMove = output<PlaceholderMoveEvent>();\n}\n","import {\n ChangeDetectionStrategy,\n Component,\n computed,\n ElementRef,\n inject,\n input,\n NgZone,\n OnDestroy,\n OnInit,\n signal,\n} from '@angular/core';\nimport {\n VDND_OFFSET_ROWS_VIEWPORT,\n VDND_VIRTUAL_VIEWPORT,\n VdndVirtualViewport,\n} from '../tokens/virtual-viewport.token';\nimport { VDND_SCROLL_CONTAINER, VdndScrollContainer } from '../tokens/scroll-container.token';\nimport { AutoScrollConfig, AutoScrollService } from '../services/auto-scroll.service';\nimport {\n bindRafThrottledScrollTopSignal,\n bindResizeObserverHeightSignal,\n} from '../utils/dom-signal-bindings';\nimport { createAutoScrollRegistration } from '../utils/auto-scroll-registration';\nimport type { VirtualScrollStrategy } from '../models/virtual-scroll-strategy';\nimport { FixedHeightStrategy } from '../strategies/fixed-height.strategy';\nimport { DynamicHeightStrategy } from '../strategies/dynamic-height.strategy';\n\n/**\n * A virtual viewport component that provides efficient wrapper-based positioning\n * for virtual scrolling. This component acts as the scroll container and provides\n * a content wrapper with GPU-accelerated transform positioning.\n *\n * Use this component when you need virtual scrolling with optimal performance.\n * Items rendered inside via `*vdndVirtualFor` will be positioned using a single\n * transform on the wrapper, rather than individual absolute positioning.\n *\n * @example\n * Basic usage:\n * ```html\n * <vdnd-virtual-viewport [itemHeight]=\"50\" style=\"height: 400px;\">\n * <ng-container *vdndVirtualFor=\"let item of items(); trackBy: trackById\">\n * <div class=\"item\">{{ item.name }}</div>\n * </ng-container>\n * </vdnd-virtual-viewport>\n * ```\n *\n * @example\n * With dynamic item heights:\n * ```html\n * <vdnd-virtual-viewport\n * [itemHeight]=\"50\"\n * [dynamicItemHeight]=\"true\"\n * style=\"height: 400px;\">\n * <ng-container *vdndVirtualFor=\"let item of items(); trackBy: trackById\">\n * <div class=\"item\">{{ item.name }}</div>\n * </ng-container>\n * </vdnd-virtual-viewport>\n * ```\n */\n@Component({\n selector: 'vdnd-virtual-viewport',\n changeDetection: ChangeDetectionStrategy.OnPush,\n providers: [\n { provide: VDND_VIRTUAL_VIEWPORT, useExisting: VirtualViewportComponent },\n { provide: VDND_OFFSET_ROWS_VIEWPORT, useExisting: VirtualViewportComponent },\n { provide: VDND_SCROLL_CONTAINER, useExisting: VirtualViewportComponent },\n ],\n host: {\n class: 'vdnd-virtual-viewport',\n // Read by the drag index calculator: this element scrolls its own rows, which start\n // data-content-offset px below the top of the scroll area\n 'data-virtual-viewport': '',\n '[attr.data-content-offset]': 'contentOffset()',\n },\n styles: `\n :host {\n display: block;\n overflow: auto;\n position: relative;\n /* Disable browser scroll anchoring to prevent scroll position adjustments\n when DOM changes (e.g., placeholder position updates during drag) */\n overflow-anchor: none;\n }\n\n .vdnd-viewport-spacer {\n position: absolute;\n left: 0;\n width: 1px;\n visibility: hidden;\n pointer-events: none;\n }\n\n .vdnd-viewport-content {\n position: absolute;\n left: 0;\n right: 0;\n will-change: transform;\n }\n `,\n template: `\n <!-- Spacer maintains total scroll height -->\n <div\n class=\"vdnd-viewport-spacer\"\n [style.top.px]=\"contentOffset()\"\n [style.height.px]=\"totalHeight()\"\n ></div>\n\n <!-- Content wrapper with GPU-accelerated transform -->\n <div\n class=\"vdnd-viewport-content\"\n [style.top.px]=\"contentOffset()\"\n [style.transform]=\"contentTransform()\"\n >\n <ng-content></ng-content>\n </div>\n `,\n})\nexport class VirtualViewportComponent\n implements VdndVirtualViewport, VdndScrollContainer, OnInit, OnDestroy\n{\n readonly #elementRef = inject(ElementRef<HTMLElement>);\n readonly #ngZone = inject(NgZone);\n readonly #autoScrollService = inject(AutoScrollService);\n\n /** Current scroll position (reactive) */\n readonly #scrollTop = signal(0);\n\n /** Measured container height (reactive) */\n readonly #containerHeight = signal(0);\n\n /** Cleanup function for scroll listener */\n #scrollCleanup: (() => void) | null = null;\n #resizeCleanup: (() => void) | null = null;\n\n /** Generated ID for auto-scroll registration */\n #generatedScrollId = `vdnd-viewport-${Math.random().toString(36).slice(2, 9)}`;\n\n /**\n * The actual first rendered item index, set by VirtualForDirective.\n * This accounts for overscan and is used for wrapper positioning.\n */\n readonly #renderStartIndex = signal(0);\n\n // ========== Inputs ==========\n\n /** Height of each item in pixels (used as estimate in dynamic mode) */\n itemHeight = input.required<number>();\n\n /**\n * Enable dynamic item height mode.\n * When true, items are auto-measured via ResizeObserver and `itemHeight`\n * serves as the initial estimate for unmeasured items.\n */\n dynamicItemHeight = input<boolean>(false);\n\n /** Offset for content below headers (in pixels) */\n contentOffset = input<number>(0);\n\n /** Unique ID for this scroll container (used for auto-scroll registration) */\n scrollContainerId = input<string>();\n\n /** Whether auto-scroll is enabled when dragging near edges */\n autoScrollEnabled = input<boolean>(true);\n\n /** Auto-scroll configuration */\n autoScrollConfig = input<Partial<AutoScrollConfig>>({});\n\n // ========== Strategy ==========\n\n /** The virtual scroll strategy, created based on dynamicItemHeight input */\n readonly #strategy = computed<VirtualScrollStrategy>(() => {\n const height = this.itemHeight();\n return this.dynamicItemHeight()\n ? new DynamicHeightStrategy(height)\n : new FixedHeightStrategy(height);\n });\n\n get strategy(): VirtualScrollStrategy {\n return this.#strategy();\n }\n\n // ========== Computed Values ==========\n\n /** Total height of all items (for scroll height), derived from strategy item count */\n readonly totalHeight = computed(() => {\n const s = this.#strategy();\n s.version();\n return s.getTotalHeight(s.getItemCount());\n });\n\n /** Transform for content wrapper positioning */\n readonly contentTransform = computed(() => {\n const startIndex = this.#renderStartIndex();\n const s = this.#strategy();\n s.version();\n const offset = s.getOffsetForIndex(startIndex);\n return `translateY(${offset}px)`;\n });\n\n // ========== VdndVirtualViewport Implementation ==========\n\n scrollTop(): number {\n return this.#scrollTop();\n }\n\n containerHeight(): number {\n return this.#containerHeight();\n }\n\n get nativeElement(): HTMLElement {\n return this.#elementRef.nativeElement;\n }\n\n /**\n * Called by VirtualForDirective to inform this viewport of the actual\n * first rendered item index. Used for wrapper positioning.\n */\n setRenderStartIndex(index: number): void {\n this.#renderStartIndex.set(index);\n }\n\n getOffsetForIndex(index: number): number {\n return this.#strategy().getOffsetForIndex(index);\n }\n\n // ========== VdndScrollContainer Implementation ==========\n\n scrollTo(options: ScrollToOptions): void {\n this.nativeElement.scrollTo(options);\n }\n\n scrollBy(delta: number): void {\n const newPosition = Math.max(\n 0,\n Math.min(\n this.scrollTop() + delta,\n this.nativeElement.scrollHeight - this.nativeElement.clientHeight,\n ),\n );\n this.scrollTo({ top: newPosition });\n }\n\n // ========== Lifecycle ==========\n\n constructor() {\n createAutoScrollRegistration({\n autoScrollService: this.#autoScrollService,\n getElement: () => this.nativeElement,\n getId: () => this.scrollContainerId() ?? this.#generatedScrollId,\n enabled: () => this.autoScrollEnabled(),\n config: () => this.autoScrollConfig(),\n });\n }\n\n ngOnInit(): void {\n this.#setupScrollListener();\n this.#setupResizeObserver();\n }\n\n ngOnDestroy(): void {\n this.#scrollCleanup?.();\n this.#resizeCleanup?.();\n }\n\n // ========== Private Methods ==========\n\n /** Minimum scroll delta (px) to trigger signal update */\n readonly #scrollThreshold = 5;\n\n #setupScrollListener(): void {\n this.#scrollCleanup = bindRafThrottledScrollTopSignal({\n element: this.nativeElement,\n ngZone: this.#ngZone,\n scrollTop: this.#scrollTop,\n thresholdPx: this.#scrollThreshold,\n });\n }\n\n #setupResizeObserver(): void {\n this.#resizeCleanup = bindResizeObserverHeightSignal({\n element: this.nativeElement,\n ngZone: this.#ngZone,\n height: this.#containerHeight,\n minDeltaPx: 1,\n });\n }\n}\n","import { Directive, ElementRef, inject } from '@angular/core';\n\n/**\n * Marks an element as the header content for a `vdnd-virtual-content` component.\n *\n * Place this directive on a projected element inside `<vdnd-virtual-content>`.\n * The component will automatically measure the header's height via ResizeObserver\n * and use it as the content offset for virtual scroll calculations.\n *\n * This eliminates the need for manual ResizeObserver boilerplate that was\n * previously required with the `[contentOffset]` input.\n *\n * @example\n * ```html\n * <vdnd-virtual-content [itemHeight]=\"50\">\n * <div class=\"page-header\" vdndContentHeader>\n * <h1>My List</h1>\n * </div>\n * <ng-container *vdndVirtualFor=\"let item of items(); trackBy: trackById\">\n * <div>{{ item.name }}</div>\n * </ng-container>\n * </vdnd-virtual-content>\n * ```\n */\n@Directive({\n selector: '[vdndContentHeader]',\n})\nexport class ContentHeaderDirective {\n readonly elementRef = inject(ElementRef<HTMLElement>);\n}\n","import {\n ChangeDetectionStrategy,\n Component,\n computed,\n contentChild,\n effect,\n ElementRef,\n inject,\n input,\n NgZone,\n PLATFORM_ID,\n signal,\n} from '@angular/core';\nimport { isPlatformBrowser } from '@angular/common';\nimport { VDND_VIRTUAL_VIEWPORT, VdndVirtualViewport } from '../tokens/virtual-viewport.token';\nimport { VDND_SCROLL_CONTAINER, VdndScrollContainer } from '../tokens/scroll-container.token';\nimport type { VirtualScrollStrategy } from '../models/virtual-scroll-strategy';\nimport { FixedHeightStrategy } from '../strategies/fixed-height.strategy';\nimport { DynamicHeightStrategy } from '../strategies/dynamic-height.strategy';\nimport { ContentHeaderDirective } from '../directives/content-header.directive';\n\n/**\n * A virtual content component that provides wrapper-based positioning\n * for virtual scrolling within an EXTERNAL scroll container.\n *\n * Use this component when you need virtual scrolling alongside other content\n * (headers, footers) within a shared scroll container. The component provides\n * a content wrapper with GPU-accelerated transform positioning while delegating\n * scroll handling to the parent `vdndScrollable` container.\n *\n * Headers marked with `vdndContentHeader` are automatically measured via\n * ResizeObserver — no manual offset calculation needed.\n *\n * @example\n * Content projection with auto-measured header:\n * ```html\n * <div vdndScrollable style=\"overflow: auto; height: 100vh;\">\n * <vdnd-virtual-content [itemHeight]=\"50\">\n * <div class=\"header\" vdndContentHeader>Welcome!</div>\n * <ng-container *vdndVirtualFor=\"let item of items(); trackBy: trackById\">\n * <div class=\"item\">{{ item.name }}</div>\n * </ng-container>\n * </vdnd-virtual-content>\n * </div>\n * ```\n *\n * @example\n * Manual offset (escape hatch):\n * ```html\n * <div vdndScrollable style=\"overflow: auto; height: 100vh;\">\n * <div class=\"header\" #header>Welcome!</div>\n * <vdnd-virtual-content [itemHeight]=\"50\" [contentOffset]=\"header.offsetHeight\">\n * <ng-container *vdndVirtualFor=\"let item of items(); trackBy: trackById\">\n * <div class=\"item\">{{ item.name }}</div>\n * </ng-container>\n * </vdnd-virtual-content>\n * </div>\n * ```\n */\n@Component({\n selector: 'vdnd-virtual-content',\n changeDetection: ChangeDetectionStrategy.OnPush,\n providers: [\n { provide: VDND_VIRTUAL_VIEWPORT, useExisting: VirtualContentComponent },\n { provide: VDND_SCROLL_CONTAINER, useExisting: VirtualContentComponent },\n ],\n host: {\n class: 'vdnd-virtual-content',\n '[attr.data-content-offset]': 'effectiveContentOffset()',\n '[attr.data-item-height]': 'itemHeight()',\n '[attr.data-total-items]': 'totalItems()',\n },\n styles: `\n :host {\n display: block;\n position: relative;\n }\n\n .vdnd-virtual-area {\n position: relative;\n }\n\n .vdnd-content-spacer {\n position: absolute;\n top: 0;\n left: 0;\n width: 1px;\n visibility: hidden;\n pointer-events: none;\n }\n\n .vdnd-content-wrapper {\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n will-change: transform;\n }\n `,\n template: `\n <!-- Projected header — in normal document flow, auto-measured via ResizeObserver -->\n <ng-content select=\"[vdndContentHeader]\" />\n\n <!-- Virtual area — sized to totalHeight, contains absolute-positioned spacer + wrapper -->\n <div class=\"vdnd-virtual-area\" [style.height.px]=\"totalHeight()\">\n <!-- Spacer maintains scroll height for the virtual list portion -->\n <div class=\"vdnd-content-spacer\" [style.height.px]=\"totalHeight()\"></div>\n\n <!-- Content wrapper with GPU-accelerated transform -->\n <div class=\"vdnd-content-wrapper\" [style.transform]=\"contentTransform()\">\n <ng-content />\n </div>\n </div>\n `,\n})\nexport class VirtualContentComponent implements VdndVirtualViewport, VdndScrollContainer {\n readonly #elementRef = inject(ElementRef<HTMLElement>);\n readonly #ngZone = inject(NgZone);\n readonly #isBrowser = isPlatformBrowser(inject(PLATFORM_ID));\n\n /**\n * The parent scroll container injected via skip-self to get the actual scrollable element.\n * We provide our own VDND_SCROLL_CONTAINER with adjusted values to children.\n */\n readonly #parentScrollContainer = inject(VDND_SCROLL_CONTAINER, { skipSelf: true });\n\n // ========== Content Queries ==========\n\n /** Projected header directive (if any) */\n private readonly headerDirective = contentChild(ContentHeaderDirective);\n\n // ========== Inputs ==========\n\n /** Height of each item in pixels (used as estimate in dynamic mode) */\n itemHeight = input.required<number>();\n\n /**\n * Offset for content above the virtual list (e.g., header height).\n * When a `vdndContentHeader` is projected, this input is ignored —\n * the offset is auto-measured via ResizeObserver.\n * Use this input only when the header lives outside the component.\n */\n contentOffset = input<number>(0);\n\n /**\n * Enable dynamic item height mode.\n * When true, items are auto-measured via ResizeObserver and `itemHeight`\n * serves as the initial estimate for unmeasured items.\n */\n dynamicItemHeight = input<boolean>(false);\n\n // ========== Internal State ==========\n\n /**\n * The actual first rendered item index, set by VirtualForDirective.\n * This accounts for overscan and is used for wrapper positioning.\n */\n readonly #renderStartIndex = signal(0);\n\n /** Auto-measured header height from ResizeObserver */\n readonly #measuredHeaderHeight = signal(0);\n\n // ========== Strategy ==========\n\n /** The virtual scroll strategy, created based on dynamicItemHeight input */\n readonly #strategy = computed<VirtualScrollStrategy>(() => {\n const height = this.itemHeight();\n return this.dynamicItemHeight()\n ? new DynamicHeightStrategy(height)\n : new FixedHeightStrategy(height);\n });\n\n get strategy(): VirtualScrollStrategy {\n return this.#strategy();\n }\n\n // ========== Computed Values ==========\n\n /** Total item count, derived from strategy (populated by VirtualForDirective) */\n readonly totalItems = computed(() => {\n const s = this.#strategy();\n s.version();\n return s.getItemCount();\n });\n\n /** Total height of all items (for scroll height) */\n readonly totalHeight = computed(() => {\n const s = this.#strategy();\n s.version();\n return s.getTotalHeight(s.getItemCount());\n });\n\n /**\n * Effective content offset: when a `vdndContentHeader` directive is projected,\n * returns the auto-measured header height. Otherwise falls back to the\n * `contentOffset` input for backward compatibility.\n */\n readonly effectiveContentOffset = computed(() => {\n const header = this.headerDirective();\n return header ? this.#measuredHeaderHeight() : this.contentOffset();\n });\n\n /**\n * Adjusted scroll position - subtracts the content offset so the virtual scroll\n * calculates visible items correctly relative to where the list starts.\n */\n readonly #adjustedScrollTop = computed(() => {\n return Math.max(0, this.#parentScrollContainer.scrollTop() - this.effectiveContentOffset());\n });\n\n /** Transform for content wrapper positioning */\n readonly contentTransform = computed(() => {\n const startIndex = this.#renderStartIndex();\n const s = this.#strategy();\n s.version();\n const offset = s.getOffsetForIndex(startIndex);\n return `translateY(${offset}px)`;\n });\n\n constructor() {\n this.#setupHeaderMeasurement();\n }\n\n // ========== VdndVirtualViewport Implementation ==========\n\n /** Adjusted scroll position relative to the virtual list start */\n scrollTop(): number {\n return this.#adjustedScrollTop();\n }\n\n containerHeight(): number {\n return this.#parentScrollContainer.containerHeight();\n }\n\n get nativeElement(): HTMLElement {\n return this.#elementRef.nativeElement;\n }\n\n /**\n * Called by VirtualForDirective to inform this viewport of the actual\n * first rendered item index. Used for wrapper positioning.\n */\n setRenderStartIndex(index: number): void {\n this.#renderStartIndex.set(index);\n }\n\n getOffsetForIndex(index: number): number {\n return this.#strategy().getOffsetForIndex(index);\n }\n\n // ========== VdndScrollContainer Implementation ==========\n\n /**\n * Scroll to a specific position, adjusting for content offset.\n */\n scrollTo(options: ScrollToOptions): void {\n const adjustedOptions = { ...options };\n if (adjustedOptions.top !== undefined) {\n // Add offset back when scrolling to ensure correct position\n adjustedOptions.top += this.effectiveContentOffset();\n }\n this.#parentScrollContainer.scrollTo(adjustedOptions);\n }\n\n // ========== Private Methods ==========\n\n /**\n * Sets up an effect that observes the projected header directive's element\n * with a ResizeObserver, keeping `#measuredHeaderHeight` in sync.\n */\n #setupHeaderMeasurement(): void {\n effect((onCleanup) => {\n const dir = this.headerDirective();\n if (!dir) {\n this.#measuredHeaderHeight.set(0);\n return;\n }\n\n // Server rendering: no layout to measure, and no ResizeObserver\n if (!this.#isBrowser) {\n return;\n }\n\n const el = dir.elementRef.nativeElement;\n this.#measuredHeaderHeight.set(el.offsetHeight);\n\n let observer: ResizeObserver | null = null;\n this.#ngZone.runOutsideAngular(() => {\n observer = new ResizeObserver((entries) => {\n for (const entry of entries) {\n const height =\n entry.borderBoxSize?.[0]?.blockSize ?? (entry.target as HTMLElement).offsetHeight;\n this.#measuredHeaderHeight.set(height);\n }\n });\n observer.observe(el, { box: 'border-box' });\n });\n\n onCleanup(() => observer?.disconnect());\n });\n }\n}\n","import { afterNextRender, EnvironmentInjector, NgZone } from '@angular/core';\nimport { DragStateService } from '../services/drag-state.service';\nimport { KeyboardDragService } from '../services/keyboard-drag.service';\nimport { PositionCalculatorService } from '../services/position-calculator.service';\nimport { DragIndexCalculatorService } from '../services/drag-index-calculator.service';\nimport { ElementCloneService } from '../services/element-clone.service';\nimport { OverlayContainerService } from '../services/overlay-container.service';\nimport { DragEndEvent, DraggedItem, DragStartEvent } from '../models/drag-drop.models';\nimport { queryByAttribute } from '../utils/attribute-selectors';\nimport { normalizeDropDestinationIndex } from '../utils/drop-index-normalization';\n\n/**\n * Context from the directive needed for keyboard drag operations.\n */\nexport interface KeyboardDragContext {\n element: HTMLElement;\n draggableId: string;\n groupName: string | null;\n data: unknown;\n}\n\n/**\n * Callbacks from the handler back into the directive for events.\n */\nexport interface KeyboardDragCallbacks {\n onDragStart: (event: DragStartEvent) => void;\n onDragEnd: (event: DragEndEvent) => void;\n getParentDroppableId: () => string | null;\n calculateSourceIndex: (element: HTMLElement, droppableElement: HTMLElement | null) => number;\n}\n\n/**\n * Dependencies injected from the directive (non-injectable handler).\n */\nexport interface KeyboardDragDeps {\n dragState: DragStateService;\n keyboardDrag: KeyboardDragService;\n positionCalculator: PositionCalculatorService;\n dragIndexCalculator: DragIndexCalculatorService;\n elementClone: ElementCloneService;\n overlayContainer: OverlayContainerService;\n ngZone: NgZone;\n envInjector: EnvironmentInjector;\n callbacks: KeyboardDragCallbacks;\n getContext: () => KeyboardDragContext;\n}\n\n/**\n * Handles keyboard-initiated drag operations (Space to start, arrows to move, Space/Enter to drop).\n *\n * Extracted from DraggableDirective to encapsulate:\n * - Starting/completing/cancelling keyboard drags\n * - Document-level keyboard listener during active drag\n * - Focus restoration after drag ends\n * - Cross-list movement via arrow keys\n *\n * Provides a unified `handleKey()` method that eliminates the duplicated\n * key→action dispatch that previously existed in both host bindings and\n * a document-level listener.\n */\nexport class KeyboardDragHandler {\n readonly #deps: KeyboardDragDeps;\n #boundKeyDown: ((e: KeyboardEvent) => void) | null = null;\n /**\n * The drag this handler started. Keyboard drag state is shared by every draggable, so a key\n * that reaches another item (one focused by a click during the drag, for example) must not\n * move, drop or cancel this drag in that item's name.\n */\n #ownDrag: DraggedItem | null = null;\n\n constructor(deps: KeyboardDragDeps) {\n this.#deps = deps;\n this.#boundKeyDown = this.#onDocumentKeyDown.bind(this);\n }\n\n /**\n * Whether a keyboard drag this handler started is active.\n */\n isActive(): boolean {\n return (\n this.#ownDrag !== null &&\n this.#deps.keyboardDrag.isActive() &&\n this.#deps.dragState.draggedItem() === this.#ownDrag\n );\n }\n\n /**\n * Start a keyboard drag operation.\n */\n activate(): void {\n const ctx = this.#deps.getContext();\n if (!ctx.groupName) {\n return;\n }\n\n const element = ctx.element;\n const rect = element.getBoundingClientRect();\n\n // Find the parent droppable\n const droppableElement = this.#deps.positionCalculator.getDroppableParent(\n element,\n ctx.groupName,\n );\n if (!droppableElement) {\n return;\n }\n\n const droppableId = this.#deps.positionCalculator.getDroppableId(droppableElement);\n if (!droppableId) {\n return;\n }\n\n // Calculate source index\n const sourceIndex = this.#deps.callbacks.calculateSourceIndex(element, droppableElement);\n\n // Get total item count from the droppable\n const totalItemCount = this.#deps.dragIndexCalculator.getTotalItemCount({\n droppableElement,\n isSameList: false,\n draggedItemHeight: rect.height,\n });\n\n // Clone element BEFORE updating drag state.\n // Template-first: skip the clone when a template-based preview is mounted.\n const clonedElement = this.#deps.overlayContainer.hasTemplatePreview()\n ? undefined\n : this.#deps.elementClone.cloneElement(element);\n\n // Start keyboard drag\n this.#deps.keyboardDrag.startKeyboardDrag(\n {\n draggableId: ctx.draggableId,\n droppableId,\n element,\n clonedElement,\n height: rect.height,\n width: rect.width,\n data: ctx.data,\n },\n sourceIndex,\n totalItemCount,\n droppableId,\n );\n this.#ownDrag = this.#deps.dragState.draggedItem();\n\n // Add document-level keyboard listener (since element is hidden with display:none)\n this.#deps.ngZone.runOutsideAngular(() => {\n document.addEventListener('keydown', this.#boundKeyDown!);\n });\n\n // Emit drag start event\n this.#deps.callbacks.onDragStart({\n draggableId: ctx.draggableId,\n droppableId,\n data: ctx.data,\n position: { x: rect.left, y: rect.top },\n sourceIndex,\n });\n }\n\n /**\n * Unified key dispatch. Returns true if the key was handled.\n * Used by both host bindings and the document-level listener.\n *\n * Handled keys are consumed entirely (preventDefault + stopPropagation): right after pickup\n * the source element can still be focused because Angular has not applied display:none yet,\n * and without stopping propagation the same keydown would be processed by both the element's\n * host binding and the document-level listener — moving the item two positions per press.\n */\n handleKey(event: KeyboardEvent): boolean {\n if (!this.isActive()) {\n return false;\n }\n\n const handled = this.#dispatchKey(event.key);\n\n if (handled) {\n event.preventDefault();\n event.stopPropagation();\n }\n\n return handled;\n }\n\n /**\n * Execute the drag action for a key. Returns true if the key maps to an action.\n */\n #dispatchKey(key: string): boolean {\n switch (key) {\n case ' ': // Space\n case 'Enter':\n this.complete();\n return true;\n case 'Escape':\n case 'Tab':\n this.cancel();\n return true;\n case 'ArrowUp':\n this.#deps.keyboardDrag.moveUp();\n return true;\n case 'ArrowDown':\n this.#deps.keyboardDrag.moveDown();\n return true;\n case 'ArrowLeft':\n this.#moveToAdjacentDroppable('left');\n return true;\n case 'ArrowRight':\n this.#moveToAdjacentDroppable('right');\n return true;\n default:\n return false;\n }\n }\n\n /**\n * Complete a keyboard drag operation (drop the item).\n */\n complete(): void {\n const ctx = this.#deps.getContext();\n const sourceIndex = this.#deps.dragState.sourceIndex() ?? 0;\n const activeDroppableId = this.#deps.dragState.activeDroppableId();\n\n // Revalidate the active target: it may have been disabled after the drag navigated\n // into it. A disabled (or missing) target is not a valid drop — report no destination.\n // The droppable's own disabled guard suppresses the drop event, keeping dragEnd and\n // drop consistent (non-cancelled dragEnd with destinationIndex: null, no drop).\n const hasValidTarget =\n activeDroppableId !== null &&\n !this.#deps.positionCalculator.isDroppableDisabledById(activeDroppableId);\n\n const destinationIndex = hasValidTarget\n ? normalizeDropDestinationIndex({\n sourceIndex,\n placeholderIndex: this.#deps.dragState.placeholderIndex(),\n sourceDroppableId: this.#deps.dragState.sourceDroppableId(),\n activeDroppableId,\n })\n : null;\n\n // Remove document listener\n this.#cleanupDocumentListener();\n\n // Clear droppable metadata cache from this drag session\n this.#deps.dragIndexCalculator.clearCache();\n\n const event: DragEndEvent = {\n draggableId: ctx.draggableId,\n droppableId: this.#deps.callbacks.getParentDroppableId() ?? '',\n cancelled: false,\n data: ctx.data,\n sourceIndex,\n destinationIndex,\n };\n\n // The item stays in its source list when there is no valid target\n const fallbackDroppableId = hasValidTarget\n ? activeDroppableId\n : this.#deps.dragState.sourceDroppableId();\n\n this.#endInZone(() => {\n this.#deps.callbacks.onDragEnd(event);\n // Ends the drag state, which delivers the drop\n this.#deps.keyboardDrag.completeKeyboardDrag();\n // Restore focus to the moved element after state updates\n this.#restoreFocus(ctx.draggableId, fallbackDroppableId);\n });\n }\n\n /**\n * Cancel a keyboard drag operation.\n */\n cancel(): void {\n const ctx = this.#deps.getContext();\n const sourceIndex = this.#deps.dragState.sourceIndex() ?? 0;\n // A cancelled item goes back to its source list\n const sourceDroppableId = this.#deps.dragState.sourceDroppableId();\n\n // Remove document listener\n this.#cleanupDocumentListener();\n\n // Clear droppable metadata cache from this drag session\n this.#deps.dragIndexCalculator.clearCache();\n\n const event: DragEndEvent = {\n draggableId: ctx.draggableId,\n droppableId: this.#deps.callbacks.getParentDroppableId() ?? '',\n cancelled: true,\n data: ctx.data,\n sourceIndex,\n destinationIndex: null,\n };\n\n this.#endInZone(() => {\n this.#deps.callbacks.onDragEnd(event);\n this.#deps.keyboardDrag.cancelKeyboardDrag();\n // Restore focus to the original element after state updates\n this.#restoreFocus(ctx.draggableId, sourceDroppableId);\n });\n }\n\n /**\n * Run a drag end (dragEnd, the state reset that delivers drop, the focus restore) in one\n * entry into Angular's zone. The document listener runs outside it; with zone.js a\n * template listener marks its view dirty but schedules no render, and each entry renders\n * when it is left, so this renders the end once, with focus restored in that render. A\n * no-op when zoneless.\n */\n #endInZone(end: () => void): void {\n this.#deps.ngZone.run(end);\n }\n\n /**\n * Teardown — remove any active document listener.\n */\n destroy(): void {\n this.#cleanupDocumentListener();\n }\n\n /**\n * Restore focus to the dragged element after keyboard drag ends.\n * Uses afterNextRender to ensure Angular has finished updating the DOM\n * (element is no longer hidden after isDragging() becomes false).\n *\n * Uses EnvironmentInjector to ensure callback runs even if the directive\n * is destroyed during cross-list moves.\n *\n * `fallbackDroppableId` is the list whose first draggable gets focus when the element is not\n * rendered (for example scrolled out of a virtual list). Callers read it before ending the\n * drag, which clears the drag state.\n */\n #restoreFocus(draggableId: string, fallbackDroppableId: string | null): void {\n afterNextRender(\n () => {\n const element = queryByAttribute<HTMLElement>(document, 'data-draggable-id', draggableId);\n\n if (element) {\n element.focus();\n } else if (fallbackDroppableId) {\n // Fallback: focus the first draggable in the list the item ended up in\n const container = this.#deps.positionCalculator.getDroppableById(fallbackDroppableId);\n const firstDraggable = container?.querySelector<HTMLElement>('[data-draggable-id]');\n firstDraggable?.focus();\n }\n },\n { injector: this.#deps.envInjector },\n );\n }\n\n /**\n * Move to an adjacent droppable in the specified direction.\n */\n #moveToAdjacentDroppable(direction: 'left' | 'right'): void {\n const currentDroppableId = this.#deps.dragState.activeDroppableId();\n if (!currentDroppableId) {\n return;\n }\n\n const groupName = this.#deps.getContext().groupName;\n if (!groupName) {\n return;\n }\n const adjacent = this.#deps.positionCalculator.findAdjacentDroppable(\n currentDroppableId,\n direction,\n groupName,\n );\n\n if (!adjacent) {\n return;\n }\n\n // Derive the destination list's item count from DragIndexCalculatorService — the single\n // source of truth that correctly handles registered strategies, dynamic-height lists, and\n // vdnd-virtual-content (page-scroll) lists. Arrowing back to the origin lands on the source\n // list, so compute isSameList rather than assuming a distinct target.\n const itemCount = this.#deps.dragIndexCalculator.getTotalItemCount({\n droppableElement: adjacent.element,\n isSameList: adjacent.id === this.#deps.dragState.sourceDroppableId(),\n draggedItemHeight: this.#deps.dragState.draggedItem()?.height ?? 0,\n });\n\n // Maintain the current target index (clamped to the new list's size)\n const currentTargetIndex = this.#deps.keyboardDrag.targetIndex() ?? 0;\n const targetIndex = Math.min(currentTargetIndex, itemCount);\n\n this.#deps.keyboardDrag.moveToDroppable(adjacent.id, targetIndex, itemCount);\n }\n\n /**\n * Document-level keydown listener active during keyboard drag.\n */\n #onDocumentKeyDown(event: KeyboardEvent): void {\n // The drag ended without this handler (its state was reset elsewhere): stop listening, or\n // this listener would also take the keys of the next keyboard drag\n if (!this.isActive()) {\n this.#cleanupDocumentListener();\n return;\n }\n this.handleKey(event);\n }\n\n /**\n * Remove the document-level keyboard listener.\n */\n #cleanupDocumentListener(): void {\n this.#ownDrag = null;\n // Server rendering destroys the directive without a global document, and never added it\n if (this.#boundKeyDown && typeof document !== 'undefined') {\n document.removeEventListener('keydown', this.#boundKeyDown);\n }\n }\n}\n","/**\n * Elements inside a draggable that keep their own interaction: pressing one never starts a\n * pointer drag, and Space pressed on one never starts a keyboard drag.\n */\nexport const INTERACTIVE_ELEMENT_SELECTOR = 'button, input, textarea, select, [contenteditable]';\n\n/** Class that excludes the element carrying it, and everything inside it, from starting a drag. */\nexport const NO_DRAG_CLASS = 'no-drag';\n\n/**\n * The `no-drag` element inside `draggable` (the draggable itself included) that contains\n * `target`, or null. A `no-drag` ancestor of the draggable does not count.\n */\nexport function findNoDragElement(target: Element, draggable: Element): Element | null {\n const noDrag = target.closest(`.${NO_DRAG_CLASS}`);\n return noDrag !== null && draggable.contains(noDrag) ? noDrag : null;\n}\n","import { NgZone } from '@angular/core';\nimport { CursorPosition } from '../models/drag-drop.models';\nimport { findNoDragElement, INTERACTIVE_ELEMENT_SELECTOR } from '../utils/interactive-elements';\n\n/**\n * Callbacks from the handler back into the directive for drag lifecycle.\n */\nexport interface PointerDragCallbacks {\n onDragStart: (position: CursorPosition) => void;\n onDragMove: (position: CursorPosition) => void;\n onDragEnd: (cancelled: boolean) => void;\n onPendingChange: (pending: boolean) => void;\n isDragging: () => boolean;\n /** Whether a drag of another item (pointer or keyboard) is in progress. */\n isOtherDragActive: () => boolean;\n}\n\n/**\n * Context from the directive needed for pointer drag operations.\n */\nexport interface PointerDragContext {\n element: HTMLElement;\n /** The item the draggable renders (a recycled row renders another one later) */\n draggableId: string;\n groupName: string | null;\n disabled: boolean;\n dragHandle: string | undefined;\n dragThreshold: number;\n dragDelay: number;\n}\n\n/**\n * Dependencies injected from the directive (non-injectable handler).\n */\nexport interface PointerDragDeps {\n ngZone: NgZone;\n callbacks: PointerDragCallbacks;\n getContext: () => PointerDragContext;\n}\n\n/**\n * Handles pointer-based (mouse + touch) drag operations.\n *\n * Extracted from DraggableDirective to encapsulate:\n * - Pointer down / move / up lifecycle\n * - Drag threshold detection\n * - Drag delay timer\n * - Forwarding moves to the directive (DragSchedulerService coalesces them per frame)\n * - Document-level listener management\n * - Escape key cancellation during pointer drag, and cancellation when the window loses focus\n * or the page is hidden (the release would never arrive) or the system cancels the touch\n */\nexport class PointerDragHandler {\n readonly #deps: PointerDragDeps;\n\n /** Starting position of the drag */\n #startPosition: CursorPosition | null = null;\n\n /** Whether we're currently tracking a potential drag */\n #isTracking = false;\n\n /** The item the tracked press landed on */\n #pressedId: string | null = null;\n\n /** Whether the document and window listeners of a press are added */\n #listening = false;\n\n /** Identifier of the finger that pressed, for touch gestures (other fingers are ignored) */\n #touchId: number | null = null;\n\n /** Bound event handlers for cleanup */\n #boundPointerMove: ((e: MouseEvent | TouchEvent) => void) | null = null;\n #boundPointerUp: ((e: MouseEvent | TouchEvent) => void) | null = null;\n #boundKeyDown: ((e: KeyboardEvent) => void) | null = null;\n #boundWindowBlur: (() => void) | null = null;\n #boundVisibilityChange: (() => void) | null = null;\n\n /** Timer ID for drag delay */\n #delayTimerId: ReturnType<typeof setTimeout> | null = null;\n\n /** Whether the delay has been satisfied (user held long enough) */\n #delayReady = false;\n\n constructor(deps: PointerDragDeps) {\n this.#deps = deps;\n this.#boundPointerMove = this.#onPointerMove.bind(this);\n this.#boundPointerUp = this.#onPointerUp.bind(this);\n this.#boundKeyDown = this.#onEscapeKeyDown.bind(this);\n this.#boundWindowBlur = this.#onFocusLost.bind(this);\n this.#boundVisibilityChange = this.#onVisibilityChange.bind(this);\n }\n\n /**\n * The position where the user initially pressed down.\n * Used by the directive to calculate grab offset when starting drag.\n */\n getStartPosition(): CursorPosition | null {\n return this.#startPosition;\n }\n\n /**\n * Handle pointer down (mouse or touch).\n * Called from the directive's host binding.\n */\n onPointerDown(event: MouseEvent | TouchEvent, isTouch: boolean): void {\n const ctx = this.#deps.getContext();\n\n if (ctx.disabled) {\n return;\n }\n\n // Without a group, this draggable can't participate in DnD (fail gracefully).\n if (!ctx.groupName) {\n return;\n }\n\n // Check for left mouse button only\n if (!isTouch && (event as MouseEvent).button !== 0) {\n return;\n }\n\n // Check if click is on drag handle (if specified)\n if (ctx.dragHandle) {\n const target = event.target as HTMLElement;\n if (!target.closest(ctx.dragHandle)) {\n return;\n }\n }\n\n // Check for elements that should not trigger drag\n const target = event.target as HTMLElement;\n if (\n target.closest(INTERACTIVE_ELEMENT_SELECTOR) ||\n findNoDragElement(target, ctx.element) !== null\n ) {\n return;\n }\n\n // Track the finger that pressed this draggable; the others are ignored for the gesture.\n const touch = 'touches' in event ? PointerDragHandler.#pressingTouch(event, ctx.element) : null;\n if ('touches' in event && !touch) {\n return;\n }\n\n const delay = ctx.dragDelay;\n\n // For touch events with a delay configured, DON'T call preventDefault() on touchstart.\n // This allows native scrolling to work if the user swipes before the delay fires.\n // For mouse events or touch without delay, prevent default immediately to avoid\n // text selection and other default behaviors.\n if (!isTouch || delay === 0) {\n event.preventDefault();\n }\n event.stopPropagation();\n\n // A second finger on this draggable while the first is still down: keep following the first.\n if ('touches' in event && touch && this.#isTracking && this.#trackedTouch(event.touches)) {\n return;\n }\n\n // Only one drag at a time: a second finger or a press during a keyboard drag must not\n // replace the drag in progress. The press keeps the default handling above, so a mouse press\n // still doesn't focus this item (which would take the keys of a keyboard drag).\n if (this.#deps.callbacks.isOtherDragActive()) {\n return;\n }\n\n this.#isTracking = true;\n this.#pressedId = ctx.draggableId;\n if (touch) {\n this.#touchId = touch.identifier;\n this.#startPosition = { x: touch.clientX, y: touch.clientY };\n } else {\n const mouse = event as MouseEvent;\n this.#startPosition = { x: mouse.clientX, y: mouse.clientY };\n }\n\n // Handle drag delay. A repeated press (e.g. after a release the page never saw) restarts the\n // delay; the previous timer must not survive, or it fires after the gesture has ended.\n this.#cancelDelayTimer();\n if (delay > 0) {\n this.#delayTimerId = setTimeout(() => {\n this.#delayTimerId = null;\n // Another drag started while this press was held, or the press no longer applies (see\n // #isStalePress): drop it rather than show it as ready to drag.\n if (\n this.#deps.callbacks.isOtherDragActive() ||\n this.#isStalePress(this.#deps.getContext())\n ) {\n this.cleanup();\n return;\n }\n this.#delayReady = true;\n this.#deps.callbacks.onPendingChange(true); // Emit ready state when delay passes\n }, delay);\n } else {\n this.#delayReady = true;\n }\n\n // Add document-level event listeners\n this.#deps.ngZone.runOutsideAngular(() => {\n if (isTouch) {\n document.addEventListener('touchmove', this.#boundPointerMove!, { passive: false });\n document.addEventListener('touchend', this.#boundPointerUp!);\n document.addEventListener('touchcancel', this.#boundPointerUp!);\n } else {\n document.addEventListener('mousemove', this.#boundPointerMove!);\n document.addEventListener('mouseup', this.#boundPointerUp!);\n }\n // Listen for Escape key on document to cancel drag\n document.addEventListener('keydown', this.#boundKeyDown!);\n // Switching windows or tabs mid-drag means the release never reaches this page: cancel\n // instead of leaving the drag active until the next press.\n window.addEventListener('blur', this.#boundWindowBlur!);\n document.addEventListener('visibilitychange', this.#boundVisibilityChange!);\n });\n this.#listening = true;\n }\n\n /**\n * Remove listeners + cancel timers.\n * Called after pointer up or when cancelling.\n */\n cleanup(): void {\n this.#isTracking = false;\n this.#pressedId = null;\n this.#startPosition = null;\n this.#touchId = null;\n this.#deps.callbacks.onPendingChange(false); // Clear pending state on cleanup\n this.#cancelDelayTimer();\n\n // Nothing to remove unless a press added listeners (most draggables are never pressed; a\n // virtual list destroys one each time a row scrolls out). Server rendering adds none.\n if (!this.#listening) {\n return;\n }\n this.#listening = false;\n\n // Remove event listeners\n if (this.#boundPointerMove) {\n document.removeEventListener('mousemove', this.#boundPointerMove);\n document.removeEventListener('touchmove', this.#boundPointerMove);\n }\n if (this.#boundPointerUp) {\n document.removeEventListener('mouseup', this.#boundPointerUp);\n document.removeEventListener('touchend', this.#boundPointerUp);\n document.removeEventListener('touchcancel', this.#boundPointerUp);\n }\n if (this.#boundKeyDown) {\n document.removeEventListener('keydown', this.#boundKeyDown);\n }\n if (this.#boundWindowBlur) {\n window.removeEventListener('blur', this.#boundWindowBlur);\n }\n if (this.#boundVisibilityChange) {\n document.removeEventListener('visibilitychange', this.#boundVisibilityChange);\n }\n }\n\n /**\n * Teardown when the directive is destroyed: removes listeners and cancels timers.\n */\n destroy(): void {\n this.cleanup();\n }\n\n /**\n * Handle pointer move (mouse or touch).\n */\n #onPointerMove(event: MouseEvent | TouchEvent): void {\n if (!this.#isTracking) {\n return;\n }\n\n let position: CursorPosition;\n if ('touches' in event) {\n // `touches` holds every finger's current position, so the tracked finger's is there even\n // when only another finger moved\n const touch = this.#trackedTouch(event.touches) ?? this.#trackedTouch(event.changedTouches);\n if (!touch) {\n // The tracked finger is gone. While dragging, keep other fingers from scrolling the page.\n if (this.#deps.callbacks.isDragging()) {\n event.preventDefault();\n }\n return;\n }\n position = { x: touch.clientX, y: touch.clientY };\n } else {\n position = { x: event.clientX, y: event.clientY };\n }\n\n // Check if we've moved past the threshold\n if (!this.#deps.callbacks.isDragging() && this.#startPosition) {\n // Read only before the drag starts, not on every move of a drag: nothing in it matters then\n const ctx = this.#deps.getContext();\n if (this.#isStalePress(ctx)) {\n this.cleanup();\n return;\n }\n\n const distance = Math.sqrt(\n Math.pow(position.x - this.#startPosition.x, 2) +\n Math.pow(position.y - this.#startPosition.y, 2),\n );\n\n if (distance < ctx.dragThreshold) {\n return;\n }\n\n // If delay is configured and not yet ready, cancel the drag attempt\n // (user moved before the delay was satisfied).\n // DON'T call preventDefault() here - let native scrolling take over.\n if (!this.#delayReady) {\n this.#cancelDelayTimer();\n this.cleanup();\n return;\n }\n\n // Another press won the race and started its drag first: give up this one.\n if (this.#deps.callbacks.isOtherDragActive()) {\n this.cleanup();\n return;\n }\n\n // Start the drag - now we can prevent default\n event.preventDefault();\n this.#deps.callbacks.onDragStart(position);\n } else if (this.#deps.callbacks.isDragging()) {\n // Already dragging - prevent default to stop scrolling\n event.preventDefault();\n }\n\n // Only update drag if we're actually dragging\n if (!this.#deps.callbacks.isDragging()) {\n return;\n }\n\n // Notify the directive of the new position — it queues this into the scheduler\n // (DragSchedulerService) which coalesces multiple moves per frame into one RAF tick.\n this.#deps.callbacks.onDragMove(position);\n }\n\n /**\n * Handle pointer up (mouse or touch).\n */\n #onPointerUp(event: MouseEvent | TouchEvent): void {\n if (!this.#isTracking) {\n return;\n }\n\n // Another finger lifted (or was cancelled) while the tracked one is still down. Touches\n // without an identifier (malformed synthetic events) can't be told apart: any release ends.\n if (\n 'touches' in event &&\n typeof this.#touchId === 'number' &&\n this.#trackedTouch(event.changedTouches) === null &&\n this.#trackedTouch(event.touches) !== null\n ) {\n return;\n }\n\n // Only prevent default if we were actually dragging\n // Otherwise, allow native touch behavior (like scroll momentum) to complete\n // The drag end runs consumer handlers (dragEnd, drop); stop tracking even if one throws\n try {\n if (this.#deps.callbacks.isDragging()) {\n event.preventDefault();\n // The system took the touch (an incoming call, an OS gesture, too many fingers): the\n // user never released, so this is a cancel, not a drop\n this.#deps.callbacks.onDragEnd(event.type === 'touchcancel');\n }\n } finally {\n this.cleanup();\n }\n }\n\n /**\n * Whether the tracked press no longer applies to the draggable: it renders another item now, or\n * it left the page (a virtual list recycled or pooled its row).\n */\n #isStalePress(ctx: PointerDragContext): boolean {\n return ctx.draggableId !== this.#pressedId || !ctx.element.isConnected;\n }\n\n /**\n * Cancel the delay timer if active.\n */\n #cancelDelayTimer(): void {\n if (this.#delayTimerId !== null) {\n clearTimeout(this.#delayTimerId);\n this.#delayTimerId = null;\n }\n this.#delayReady = false;\n }\n\n /**\n * Handle keydown events on document to cancel drag with Escape.\n */\n #onEscapeKeyDown(event: KeyboardEvent): void {\n if (event.key === 'Escape' && this.#deps.callbacks.isDragging()) {\n try {\n this.#deps.callbacks.onDragEnd(true);\n } finally {\n this.cleanup();\n }\n }\n }\n\n /**\n * Cancel the drag (or drop the pending press) when the window loses focus.\n */\n #onFocusLost(): void {\n if (!this.#isTracking) {\n return;\n }\n\n try {\n if (this.#deps.callbacks.isDragging()) {\n this.#deps.callbacks.onDragEnd(true);\n }\n } finally {\n this.cleanup();\n }\n }\n\n /**\n * Treat the page being hidden (tab switch, app switch on mobile) as focus loss.\n */\n #onVisibilityChange(): void {\n if (document.visibilityState === 'hidden') {\n this.#onFocusLost();\n }\n }\n\n /**\n * The tracked finger in `touches`, or null. Synthetic touch events (e.g. from test tools) can\n * leave a list undefined, so a missing list counts as empty. Read by index, without copying the\n * list or creating an iterator: this runs for every touch move.\n */\n #trackedTouch(touches: TouchList | undefined): Touch | null {\n if (!touches) {\n return null;\n }\n // eslint-disable-next-line @typescript-eslint/prefer-for-of -- for...of creates an iterator\n for (let i = 0; i < touches.length; i++) {\n if (touches[i].identifier === this.#touchId) {\n return touches[i];\n }\n }\n return null;\n }\n\n /**\n * The finger that pressed this draggable: of the touches that started with this event, the\n * one on the draggable (several fingers can land in one touchstart).\n */\n static #pressingTouch(event: TouchEvent, element: HTMLElement): Touch | null {\n // Either list can be undefined on synthetic events\n const started = Array.from((event.changedTouches as TouchList | undefined) ?? []);\n const onElement = started.find(\n (touch) => touch.target instanceof Node && element.contains(touch.target),\n );\n return onElement ?? started[0] ?? Array.from(event.touches ?? [])[0] ?? null;\n }\n}\n","import {\n computed,\n Directive,\n ElementRef,\n EnvironmentInjector,\n ErrorHandler,\n inject,\n input,\n NgZone,\n OnChanges,\n OnDestroy,\n OnInit,\n output,\n signal,\n} from '@angular/core';\nimport { DragStateService } from '../services/drag-state.service';\nimport { PositionCalculatorService } from '../services/position-calculator.service';\nimport { AutoScrollService } from '../services/auto-scroll.service';\nimport { ElementCloneService } from '../services/element-clone.service';\nimport { KeyboardDragService } from '../services/keyboard-drag.service';\nimport { DragIndexCalculatorService } from '../services/drag-index-calculator.service';\nimport { OverlayContainerService } from '../services/overlay-container.service';\nimport { DragSchedulerService } from '../services/drag-scheduler.service';\nimport {\n CursorPosition,\n DragEndEvent,\n DragStartEvent,\n GrabOffset,\n} from '../models/drag-drop.models';\nimport { VDND_GROUP_TOKEN } from './droppable-group.directive';\nimport { createEffectiveGroupSignal } from '../utils/group-resolution';\nimport { KeyboardDragHandler } from '../handlers/keyboard-drag.handler';\nimport { PointerDragHandler } from '../handlers/pointer-drag.handler';\nimport { normalizeDropDestinationIndex } from '../utils/drop-index-normalization';\nimport { findNoDragElement, INTERACTIVE_ELEMENT_SELECTOR } from '../utils/interactive-elements';\n\n/** Key names as Angular's `keydown.<key>` bindings spell them, for the `event.key` values that differ */\nconst KEY_NAMES: Record<string, string> = {\n ' ': 'space',\n Esc: 'escape',\n '\\x1B': 'escape',\n Up: 'arrowup',\n Down: 'arrowdown',\n Left: 'arrowleft',\n Right: 'arrowright',\n};\n\n/** The keys an item handles */\nconst HANDLED_KEYS = new Set([\n 'space',\n 'enter',\n 'arrowup',\n 'arrowdown',\n 'arrowleft',\n 'arrowright',\n 'escape',\n]);\n\n/**\n * Makes an element draggable within the virtual scroll drag-and-drop system.\n *\n * @example\n * ```html\n * <!-- With explicit group -->\n * <div\n * vdndDraggable=\"item-1\"\n * vdndDraggableGroup=\"my-group\"\n * [vdndDraggableData]=\"item\">\n * Drag me!\n * </div>\n *\n * <!-- With inherited group from parent vdndGroup directive -->\n * <div vdndGroup=\"my-group\">\n * <div vdndDraggable=\"item-1\" [vdndDraggableData]=\"item\">\n * Drag me!\n * </div>\n * </div>\n * ```\n */\n@Directive({\n selector: '[vdndDraggable]',\n host: {\n '[attr.data-draggable-id]': 'vdndDraggable()',\n '[class.vdnd-draggable]': 'true',\n '[class.vdnd-draggable-dragging]': 'isDragging()',\n '[class.vdnd-draggable-disabled]': 'disabled()',\n '[class.vdnd-drag-pending]': 'isPending()',\n '[style.display]': 'isDragging() ? \"none\" : null',\n '[attr.aria-grabbed]': 'isDragging() ? \"true\" : \"false\"',\n '[tabindex]': 'disabled() ? -1 : 0',\n '(mousedown)': 'onPointerDown($event, false)',\n },\n})\nexport class DraggableDirective implements OnChanges, OnInit, OnDestroy {\n readonly #elementRef = inject(ElementRef<HTMLElement>);\n readonly #dragState = inject(DragStateService);\n readonly #positionCalculator = inject(PositionCalculatorService);\n readonly #autoScroll = inject(AutoScrollService);\n readonly #elementClone = inject(ElementCloneService);\n readonly #keyboardDrag = inject(KeyboardDragService);\n readonly #dragIndexCalculator = inject(DragIndexCalculatorService);\n readonly #overlayContainer = inject(OverlayContainerService);\n readonly #scheduler = inject(DragSchedulerService);\n readonly #ngZone = inject(NgZone);\n readonly #envInjector = inject(EnvironmentInjector);\n readonly #parentGroup = inject(VDND_GROUP_TOKEN, { optional: true });\n\n /** Unique identifier for this draggable */\n vdndDraggable = input.required<string>();\n\n /**\n * Drag-and-drop group name.\n * Optional when a parent `vdndGroup` directive provides the group context.\n */\n vdndDraggableGroup = input<string>();\n\n /**\n * Resolved group name - uses explicit input or falls back to parent group.\n * Returns null (and disables drag) if neither is available.\n */\n readonly #effectiveGroup = createEffectiveGroupSignal({\n explicitGroup: this.vdndDraggableGroup,\n parentGroup: this.#parentGroup,\n elementId: this.vdndDraggable,\n elementType: 'draggable',\n });\n\n /** Optional data associated with this draggable */\n vdndDraggableData = input<unknown>();\n\n /** Whether this draggable is disabled */\n disabled = input<boolean>(false);\n\n /** CSS selector for drag handle (if not provided, entire element is draggable) */\n dragHandle = input<string>();\n\n /** Minimum distance to move before drag starts (prevents accidental drags) */\n dragThreshold = input<number>(5);\n\n /**\n * Delay in milliseconds before drag starts after pointer down.\n * User must hold without moving for this duration.\n * Set to 0 for immediate drag (default behavior).\n */\n dragDelay = input<number>(0);\n\n /**\n * Lock dragging by freezing one axis. The value names the axis that stays\n * fixed: `'x'` freezes the X coordinate (vertical-only movement), `'y'`\n * freezes the Y coordinate (horizontal-only movement). `null` allows free\n * movement. Note: this is the opposite of Angular CDK's `cdkDragLockAxis`.\n */\n lockAxis = input<'x' | 'y' | null>(null);\n\n /** Emits when drag starts */\n dragStart = output<DragStartEvent>();\n\n /** Emits when drag ends */\n dragEnd = output<DragEndEvent>();\n\n /** The item whose press is ready to drag (its delay has passed) */\n readonly #pendingId = signal<string | null>(null);\n\n /**\n * Whether this element is in the \"ready to drag\" state (delay has passed). Tied to the pressed\n * item: a recycled row that renders another item is not ready to drag.\n */\n readonly isPending = computed(() => {\n const pendingId = this.#pendingId();\n return pendingId !== null && pendingId === this.vdndDraggable();\n });\n\n /** Whether this element is currently being dragged (based on global drag state) */\n readonly isDragging = computed(() => {\n const draggedItem = this.#dragState.draggedItem();\n return draggedItem?.draggableId === this.vdndDraggable();\n });\n\n #keyboardHandler!: KeyboardDragHandler;\n #pointerHandler!: PointerDragHandler;\n\n /** Set by ngOnInit, which creates the handlers */\n #initialized = false;\n\n /**\n * Keys pressed on the item: one listener, added outside Angular's zone, instead of a\n * `(keydown.<key>)` host binding per key, as Angular adds a listener to every row for each.\n * Like those bindings, it ignores a key pressed with Shift, Ctrl, Alt or Meta, runs the handler\n * of a key it handles in the zone (so zone.js apps still render after it), prevents the key's\n * default action when the handler returns false, and reports what the handler throws to the\n * ErrorHandler. Added in the constructor, so it runs before the element's template listeners,\n * as host listeners do.\n */\n readonly #onKeydown = (event: KeyboardEvent): void => {\n if (!this.#initialized || event.shiftKey || event.ctrlKey || event.altKey || event.metaKey) {\n return;\n }\n const key = event.key ? (KEY_NAMES[event.key] ?? event.key.toLowerCase()) : '';\n if (!HANDLED_KEYS.has(key)) {\n return;\n }\n this.#ngZone.run(() => {\n try {\n if (this.#handleKey(key, event) === false) {\n event.preventDefault();\n }\n } catch (error) {\n this.#envInjector.get(ErrorHandler).handleError(error);\n }\n });\n };\n\n /**\n * Touch presses on the item. Added programmatically, not as a host binding (which Angular adds\n * without options, so non-passive): a swipe that starts on an element with a non-passive\n * touchstart listener can't scroll until the main thread has run it. With a drag delay the press\n * never cancels the scroll (the page must scroll when the user swipes before the delay passes),\n * so the listener is passive; without one it prevents the default action and is non-passive.\n * Like the keydown listener, it runs the handler in the zone (as the mousedown host binding\n * does) and reports what it throws to the ErrorHandler. Added once the inputs are set, so unlike\n * a host listener it runs after the element's template listeners.\n */\n readonly #onTouchStart = (event: TouchEvent): void => {\n if (!this.#initialized) {\n return;\n }\n this.#ngZone.run(() => {\n try {\n this.onPointerDown(event, true);\n } catch (error) {\n this.#envInjector.get(ErrorHandler).handleError(error);\n }\n });\n };\n\n /** Whether the touchstart listener is passive, or null while it isn't added */\n #touchStartPassive: boolean | null = null;\n\n constructor() {\n this.#ngZone.runOutsideAngular(() =>\n this.#elementRef.nativeElement.addEventListener('keydown', this.#onKeydown),\n );\n }\n\n /** Cached constraint flag from source droppable */\n #constrainToContainer = false;\n\n /** Element whose rect is used for clamping (scroll container or droppable itself) */\n #constraintElement: HTMLElement | null = null;\n\n /** Last raw pointer position from pointer move events (not clamped) */\n #lastRawPosition: CursorPosition | null = null;\n\n /**\n * Update the pending state and emit the change event.\n */\n #setPending(pending: boolean): void {\n this.#pendingId.set(pending ? this.vdndDraggable() : null);\n }\n\n /**\n * Find the element to use for container constraint clamping.\n * If the droppable is inside a scrollable container, use that container's rect\n * (which represents the visible viewport) instead of the droppable's rect\n * (which may extend far beyond the viewport in virtual scroll scenarios).\n */\n #findConstraintElement(droppableElement: HTMLElement | null): HTMLElement | null {\n if (!droppableElement) return null;\n const scrollable = droppableElement.closest('.vdnd-scrollable');\n return (scrollable as HTMLElement) ?? droppableElement;\n }\n\n ngOnInit(): void {\n this.#keyboardHandler = new KeyboardDragHandler({\n dragState: this.#dragState,\n keyboardDrag: this.#keyboardDrag,\n positionCalculator: this.#positionCalculator,\n dragIndexCalculator: this.#dragIndexCalculator,\n elementClone: this.#elementClone,\n overlayContainer: this.#overlayContainer,\n ngZone: this.#ngZone,\n envInjector: this.#envInjector,\n callbacks: {\n onDragStart: (event) => this.#ngZone.run(() => this.dragStart.emit(event)),\n // The keyboard handler ends the drag inside the zone (dragEnd, drop, focus restore)\n onDragEnd: (event) => this.dragEnd.emit(event),\n getParentDroppableId: () => this.#getParentDroppableId(),\n calculateSourceIndex: (el, droppable) => this.#calculateSourceIndex(el, droppable),\n },\n getContext: () => ({\n element: this.#elementRef.nativeElement,\n draggableId: this.vdndDraggable(),\n groupName: this.#effectiveGroup(),\n data: this.vdndDraggableData(),\n }),\n });\n\n this.#pointerHandler = new PointerDragHandler({\n ngZone: this.#ngZone,\n callbacks: {\n onDragStart: (position) => this.#startDrag(position),\n onDragMove: (position) => {\n // Record raw position synchronously (needed for autoscroll cursor override)\n // then queue into the scheduler's RAF loop for coalesced frame-rate processing.\n this.#lastRawPosition = position;\n this.#scheduler.queueCursorUpdate(position);\n },\n onDragEnd: (cancelled) => this.#endDrag(cancelled),\n onPendingChange: (pending) => this.#setPending(pending),\n isDragging: () => this.isDragging(),\n isOtherDragActive: () => this.#dragState.isDragging() && !this.isDragging(),\n },\n getContext: () => ({\n element: this.#elementRef.nativeElement,\n draggableId: this.vdndDraggable(),\n groupName: this.#effectiveGroup(),\n disabled: this.disabled(),\n dragHandle: this.dragHandle(),\n dragThreshold: this.dragThreshold(),\n dragDelay: this.dragDelay(),\n }),\n });\n\n this.#initialized = true;\n this.#listenForTouchStart();\n }\n\n ngOnChanges(): void {\n this.#listenForTouchStart();\n }\n\n ngOnDestroy(): void {\n this.#elementRef.nativeElement.removeEventListener('keydown', this.#onKeydown);\n this.#elementRef.nativeElement.removeEventListener('touchstart', this.#onTouchStart);\n\n // Destroyed before its first change detection: there are no handlers yet, and its inputs\n // have no values (reading a bound ID would throw).\n if (!this.#initialized) {\n return;\n }\n\n // If destroyed mid-drag, cancel to avoid stale global state / ongoing RAF loops.\n if (this.isDragging()) {\n this.#endDrag(true);\n }\n this.#pointerHandler.destroy();\n this.#keyboardHandler.destroy();\n }\n\n /**\n * Add the touchstart listener, or re-add it when the drag delay changes whether it can be\n * passive. Lifecycle hooks, not an effect: creating a view effect schedules a change detection\n * that visits every ancestor, and a virtual list creates rows on each scroll step.\n */\n #listenForTouchStart(): void {\n // The handler cancels the scroll of a touch press only when there is no delay\n const passive = this.dragDelay() !== 0;\n if (passive === this.#touchStartPassive) {\n return;\n }\n const element: HTMLElement = this.#elementRef.nativeElement;\n element.removeEventListener('touchstart', this.#onTouchStart);\n this.#ngZone.runOutsideAngular(() =>\n element.addEventListener('touchstart', this.#onTouchStart, { passive }),\n );\n this.#touchStartPassive = passive;\n }\n\n /** Run the handler of a key the item handles (see HANDLED_KEYS), returning what it returns. */\n #handleKey(key: string, event: KeyboardEvent): unknown {\n switch (key) {\n case 'space':\n return this.onKeyboardActivate(event);\n case 'enter':\n return this.onEnterKey(event);\n case 'escape':\n return this.onEscape();\n default:\n return this.onArrowKey(event);\n }\n }\n\n /**\n * Handle pointer down (mouse or touch).\n */\n protected onPointerDown(event: MouseEvent | TouchEvent, isTouch: boolean): void {\n this.#pointerHandler.onPointerDown(event, isTouch);\n }\n\n /**\n * Handle keyboard activation (space key).\n * Starts a keyboard drag if not dragging, or drops if already in keyboard drag mode.\n */\n protected onKeyboardActivate(event: Event): void {\n if (this.disabled()) {\n return;\n }\n\n // Space on a control inside the item types into it or clicks it, just as a press on\n // one never starts a pointer drag.\n if (this.#isFromNestedControl(event)) {\n return;\n }\n\n event.preventDefault();\n\n // If we're in a keyboard drag, Space drops the item\n if (this.#keyboardHandler.isActive()) {\n event.stopPropagation(); // Prevent document listener from receiving this event\n this.#keyboardHandler.complete();\n return;\n }\n\n // Another drag is in progress: don't replace it. The key goes on to the document, where a\n // keyboard drag of another item drops with it.\n if (this.#dragState.isDragging()) {\n return;\n }\n\n // Start keyboard drag. The document listener it adds must not receive this event.\n event.stopPropagation();\n this.#keyboardHandler.activate();\n }\n\n /**\n * Whether the event comes from a control (or from inside a `no-drag` element) nested inside this\n * draggable. Neither the draggable itself nor a control around it counts, so a\n * `<button vdndDraggable>` still picks up with Space, and neither does a control that is the\n * drag handle, such as a button handle. Controls inside the handle do count.\n */\n #isFromNestedControl(event: Event): boolean {\n const host = this.#elementRef.nativeElement;\n const target = event.target;\n if (!(target instanceof Element) || target === host) {\n return false;\n }\n\n if (findNoDragElement(target, host) !== null) {\n return true;\n }\n\n const control = target.closest(INTERACTIVE_ELEMENT_SELECTOR);\n if (control === null || control === host || !host.contains(control)) {\n return false;\n }\n\n const handleSelector = this.dragHandle();\n return !handleSelector || !control.matches(handleSelector);\n }\n\n /**\n * Handle Enter key (alternative to Space for dropping during keyboard drag).\n */\n protected onEnterKey(event: Event): void {\n if (this.#keyboardHandler.isActive()) {\n event.preventDefault();\n this.#keyboardHandler.complete();\n }\n }\n\n /**\n * Handle arrow keys during keyboard drag.\n */\n protected onArrowKey(event: Event): void {\n if (this.#keyboardHandler.isActive()) {\n this.#keyboardHandler.handleKey(event as KeyboardEvent);\n }\n }\n\n /**\n * Handle escape key to cancel drag (host binding, fires before element is hidden).\n */\n protected onEscape(): boolean {\n if (this.#keyboardHandler.isActive()) {\n this.#keyboardHandler.cancel();\n return false;\n }\n if (this.isDragging()) {\n this.#endDrag(true);\n this.#pointerHandler.cleanup();\n return false; // Prevents default\n }\n return true;\n }\n\n /**\n * Start the drag operation.\n */\n #startDrag(position: CursorPosition): void {\n // Clear pending state - drag is now active\n this.#setPending(false);\n\n const element = this.#elementRef.nativeElement;\n const rect = element.getBoundingClientRect();\n\n // Calculate grab offset using the START position (where user initially pressed down)\n // NOT the current position (where drag threshold was exceeded)\n // This ensures the preview maintains its position relative to where the user grabbed it\n const startPos = this.#pointerHandler.getStartPosition() ?? position;\n const grabOffset: GrabOffset = {\n x: startPos.x - rect.left,\n y: startPos.y - rect.top,\n };\n\n // Clone element BEFORE updating drag state (which triggers display:none via host binding).\n // Template-first: skip the costly getComputedStyle deep-walk when a template-based\n // preview is mounted, since that clone would never be rendered.\n const clonedElement = this.#overlayContainer.hasTemplatePreview()\n ? undefined\n : this.#elementClone.cloneElement(element);\n\n // Find droppable and calculate initial placeholder position\n // This fixes the UI glitch by ensuring placeholder is set before the element is hidden\n const groupName = this.#effectiveGroup();\n if (!groupName) {\n // Misconfigured - cancel tracking and don't start drag.\n this.#pointerHandler.cleanup();\n return;\n }\n\n const parentDroppableElement = this.#positionCalculator.getDroppableParent(element, groupName);\n const parentDroppableId = parentDroppableElement\n ? this.#positionCalculator.getDroppableId(parentDroppableElement)\n : null;\n\n // Snapshot droppable rects for this drag session so subsequent hit-testing is\n // pure geometry (no elementFromPoint layout flush per pointermove).\n this.#positionCalculator.beginDragSession(groupName);\n\n const droppableElement = this.#positionCalculator.findDroppableAtPoint(\n position.x,\n position.y,\n element,\n groupName,\n );\n\n // Cache constraint flag and element for clamping during drag\n this.#constrainToContainer =\n droppableElement?.hasAttribute('data-constrain-to-container') ?? false;\n this.#constraintElement = this.#constrainToContainer\n ? this.#findConstraintElement(droppableElement)\n : null;\n\n const activeDroppableId = droppableElement\n ? this.#positionCalculator.getDroppableId(droppableElement)\n : parentDroppableId;\n\n // Calculate source index BEFORE the element is hidden (display: none)\n // This is critical because getBoundingClientRect() returns all zeros for hidden elements\n const sourceIndex = this.#calculateSourceIndex(element, parentDroppableElement);\n\n let initialPlaceholderId: string | null = null;\n let initialPlaceholderIndex: number | null = null;\n\n if (droppableElement) {\n const indexResult = this.#dragIndexCalculator.calculatePlaceholderIndex({\n droppableElement,\n position,\n previousPosition: null,\n grabOffset,\n draggedItemHeight: rect.height,\n sourceDroppableId: parentDroppableId,\n sourceIndex,\n });\n initialPlaceholderIndex = indexResult.index;\n initialPlaceholderId = indexResult.placeholderId;\n }\n\n const lockAxis = this.lockAxis();\n\n // Register with drag state service - this triggers isDragging computed to become true\n // which will apply display:none via host binding\n // No ngZone.run() needed - signals work outside zone and effects react automatically\n this.#dragState.startDrag(\n {\n draggableId: this.vdndDraggable(),\n droppableId: parentDroppableId ?? '',\n element,\n clonedElement,\n height: rect.height,\n width: rect.width,\n data: this.vdndDraggableData(),\n },\n position,\n grabOffset,\n lockAxis,\n activeDroppableId,\n initialPlaceholderId,\n initialPlaceholderIndex,\n sourceIndex,\n undefined,\n lockAxis ? startPos : undefined,\n );\n\n // Start the scheduler RAF loop (drives pointer-move updates + autoscroll participant).\n // onTick is called each frame: when cursor is dirty, run full #updateDrag.\n this.#scheduler.start((cursor, cursorDirty) => {\n if (cursorDirty && cursor && this.isDragging()) {\n this.#updateDrag(cursor);\n }\n });\n\n // Start auto-scroll monitoring — registers as a scheduler participant.\n this.#autoScroll.startMonitoring(() => this.#recalculatePlaceholder());\n\n // Emit drag start event\n // Pointer listeners run outside Angular's zone. With zone.js a template listener marks\n // its view dirty but schedules no render, so emit inside the zone (a no-op when zoneless).\n const event: DragStartEvent = {\n draggableId: this.vdndDraggable(),\n droppableId: parentDroppableId ?? '',\n data: this.vdndDraggableData(),\n position,\n sourceIndex,\n };\n this.#ngZone.run(() => this.dragStart.emit(event));\n }\n\n /**\n * Calculate the source index of the dragged element BEFORE it's hidden.\n * This must be called before startDrag updates the state (which triggers display:none).\n * Uses strategy-based lookup when available for accurate handling of variable heights.\n */\n #calculateSourceIndex(element: HTMLElement, droppableElement: HTMLElement | null): number {\n if (!droppableElement) {\n return 0;\n }\n\n const rect = element.getBoundingClientRect();\n // The same measurement that places the placeholder: it knows each container's scroll\n // element and subtracts space reserved above the rows (contentOffset, page headers).\n const geometry = this.#dragIndexCalculator.getScrollGeometry(droppableElement, rect.height);\n const relativeY = rect.top - geometry.rect.top + geometry.scrollTop;\n\n // Try to use registered strategy for accurate offset-based lookup\n const droppableId = this.#positionCalculator.getDroppableId(droppableElement);\n if (droppableId) {\n const strategy = this.#dragIndexCalculator.getStrategyForDroppable(droppableId);\n if (strategy) {\n return strategy.findIndexAtOffset(relativeY);\n }\n }\n\n // Preserve the geometry fallback for a virtual container whose strategy is unavailable.\n if (geometry.isVirtual) {\n const itemHeight = rect.height || 50;\n return Math.round(relativeY / itemHeight);\n }\n\n // Non-virtual fallback: derive the logical index from preceding draggable siblings.\n // Geometry-based division is incorrect when the list has padding, gaps, margins,\n // or variable-height items.\n let sourceIndex = 0;\n let sibling = element.previousElementSibling;\n while (sibling) {\n if (sibling.matches('[data-draggable-id]')) {\n sourceIndex++;\n }\n sibling = sibling.previousElementSibling;\n }\n return sourceIndex;\n }\n\n /**\n * Recalculate placeholder position (called during auto-scroll).\n *\n * Scroll-only fast path: the cursor has not moved — only `scrollTop` changed.\n * When the active droppable is already known, skip hit-testing entirely and\n * recalculate only the placeholder index within that droppable. This avoids the\n * `findDroppableAtPoint` geometry scan + the `invalidateDroppableRects` DOM round-trip\n * on every autoscroll frame while still recomputing the correct insertion index.\n *\n * Falls back to the full `#updateDrag` pipeline when no droppable is active (e.g.\n * cursor drifted outside all droppables before the scroll tick fired).\n */\n #recalculatePlaceholder(): void {\n const cursorPosition = this.#dragState.cursorPosition();\n if (!cursorPosition || !this.isDragging()) {\n return;\n }\n\n const activeDroppableId = this.#dragState.activeDroppableId();\n if (activeDroppableId) {\n const droppableElement = this.#positionCalculator.getDroppableById(activeDroppableId);\n if (droppableElement) {\n const draggedItemHeight = this.#dragState.draggedItem()?.height ?? 50;\n const indexResult = this.#dragIndexCalculator.calculatePlaceholderIndex({\n droppableElement,\n position: cursorPosition,\n previousPosition: cursorPosition,\n grabOffset: this.#dragState.grabOffset(),\n draggedItemHeight,\n sourceDroppableId: this.#dragState.sourceDroppableId(),\n sourceIndex: this.#dragState.sourceIndex(),\n });\n this.#dragState.updateScrollOnlyPlaceholder(indexResult.placeholderId, indexResult.index);\n return;\n }\n }\n\n // Fallback: full recalculation when no active droppable is known.\n // Mark rects dirty first since autoscroll moved the container before the scroll event fires.\n this.#positionCalculator.invalidateDroppableRects();\n this.#updateDrag(cursorPosition);\n }\n\n /**\n * Clamp cursor position to source container boundaries when constrainToContainer is enabled.\n */\n #clampToContainer(position: CursorPosition): CursorPosition {\n if (!this.#constrainToContainer || !this.#constraintElement) {\n return position;\n }\n\n const containerRect = this.#constraintElement.getBoundingClientRect();\n const grabOffset = this.#dragState.grabOffset();\n if (!grabOffset) {\n return position;\n }\n\n const draggedItem = this.#dragState.draggedItem();\n const itemHeight = draggedItem?.height ?? 0;\n const itemWidth = draggedItem?.width ?? 0;\n\n const minY = containerRect.top + grabOffset.y + 1;\n const maxY = containerRect.bottom - (itemHeight - grabOffset.y) - 1;\n const minX = containerRect.left + grabOffset.x + 1;\n const maxX = containerRect.right - (itemWidth - grabOffset.x) - 1;\n\n return {\n x: Math.max(minX, Math.min(position.x, maxX)),\n y: Math.max(minY, Math.min(position.y, maxY)),\n };\n }\n\n /**\n * Update the drag position.\n * @param position Current cursor position\n */\n #updateDrag(position: CursorPosition): void {\n const element = this.#elementRef.nativeElement;\n const groupName = this.#effectiveGroup();\n if (!groupName) {\n // Group became unavailable mid-drag; cancel to avoid inconsistent state.\n this.#endDrag(true);\n this.#pointerHandler.cleanup();\n return;\n }\n\n // Apply axis locking to effective position for droppable detection\n // When axis is locked, use the start position for the locked axis\n const axisLock = this.lockAxis();\n const startPos = this.#pointerHandler.getStartPosition();\n let effectivePosition = position;\n\n if (axisLock && startPos) {\n effectivePosition = {\n x: axisLock === 'x' ? startPos.x : position.x,\n y: axisLock === 'y' ? startPos.y : position.y,\n };\n }\n\n // Apply container clamping after axis locking\n effectivePosition = this.#clampToContainer(effectivePosition);\n\n // Update autoscroll cursor: use raw pointer position clamped to container\n // edges (without grabOffset) so autoscroll threshold is reachable regardless\n // of where the user grabbed the item.\n if (this.#constrainToContainer && this.#constraintElement && this.#lastRawPosition) {\n const rect = this.#constraintElement.getBoundingClientRect();\n let scrollCursor: CursorPosition = this.#lastRawPosition;\n if (axisLock && startPos) {\n scrollCursor = {\n x: axisLock === 'x' ? startPos.x : scrollCursor.x,\n y: axisLock === 'y' ? startPos.y : scrollCursor.y,\n };\n }\n this.#autoScroll.setCursorOverride({\n x: Math.max(rect.left, Math.min(scrollCursor.x, rect.right)),\n y: Math.max(rect.top, Math.min(scrollCursor.y, rect.bottom)),\n });\n }\n\n // Find droppable at effective position (respects axis locking and clamping)\n const droppableElement = this.#positionCalculator.findDroppableAtPoint(\n effectivePosition.x,\n effectivePosition.y,\n element,\n groupName,\n );\n\n const activeDroppableId = droppableElement\n ? this.#positionCalculator.getDroppableId(droppableElement)\n : null;\n\n let placeholderId: string | null = null;\n let placeholderIndex: number | null = null;\n\n if (droppableElement) {\n // Calculate placeholder index based on effective position using mathematical approach\n // This is more stable than DOM-based detection because it doesn't get affected\n // by the placeholder insertion shifting elements around\n const draggedItemHeight = this.#dragState.draggedItem()?.height ?? 50;\n const indexResult = this.#dragIndexCalculator.calculatePlaceholderIndex({\n droppableElement,\n position: effectivePosition,\n previousPosition: this.#dragState.cursorPosition(),\n grabOffset: this.#dragState.grabOffset(),\n draggedItemHeight,\n sourceDroppableId: this.#dragState.sourceDroppableId(),\n sourceIndex: this.#dragState.sourceIndex(),\n });\n placeholderIndex = indexResult.index;\n placeholderId = indexResult.placeholderId;\n }\n\n // Update drag state with effective position (respects axis locking and container clamping)\n // No ngZone.run() needed - signals work outside zone and effects react automatically\n this.#dragState.updateDragPosition({\n cursorPosition: effectivePosition,\n activeDroppableId,\n placeholderId,\n placeholderIndex,\n });\n }\n\n /**\n * End the drag operation.\n */\n #endDrag(cancelled: boolean): void {\n // Flush the final pointer position for a real drop. Pointer moves only QUEUE a cursor\n // for the next RAF tick; on release the scheduler is stopped below and any un-processed\n // cursor is discarded, so without this the drop would resolve against the last\n // RAF-PROCESSED position — a release that just entered a different (e.g. newly disabled)\n // droppable could otherwise land on the previously-targeted one. Guarded on group\n // presence so it never re-enters #endDrag via #updateDrag's group-lost cancel path.\n // Cancels skip this: their destination is intentionally null.\n if (!cancelled && this.#lastRawPosition && this.isDragging() && this.#effectiveGroup()) {\n this.#updateDrag(this.#lastRawPosition);\n }\n\n // Stop the scheduler RAF loop first, then remove the autoscroll participant.\n this.#scheduler.stop();\n this.#autoScroll.stopMonitoring();\n\n // Tear down the geometric hit-testing snapshot + its viewport listeners\n this.#positionCalculator.endDragSession();\n\n // Clear droppable metadata cache from this drag session\n this.#dragIndexCalculator.clearCache();\n\n // Reset cached constraint state\n this.#constrainToContainer = false;\n this.#constraintElement = null;\n this.#lastRawPosition = null;\n\n const sourceIndex = this.#dragState.sourceIndex() ?? 0;\n const destinationIndex = cancelled\n ? null\n : normalizeDropDestinationIndex({\n sourceIndex,\n placeholderIndex: this.#dragState.placeholderIndex(),\n sourceDroppableId: this.#dragState.sourceDroppableId(),\n activeDroppableId: this.#dragState.activeDroppableId(),\n });\n\n const event: DragEndEvent = {\n draggableId: this.vdndDraggable(),\n droppableId: this.#getParentDroppableId() ?? '',\n cancelled,\n data: this.vdndDraggableData(),\n sourceIndex,\n destinationIndex,\n };\n\n // dragEnd, then the state reset that delivers drop, in ONE zone entry: listeners run\n // outside Angular's zone, and with zone.js each entry renders when it is left, so\n // separate entries would render the drag end twice. A no-op when zoneless.\n this.#ngZone.run(() => {\n this.dragEnd.emit(event);\n\n // Clear drag state - this triggers isDragging computed to become false\n if (cancelled) {\n this.#dragState.cancelDrag();\n } else {\n this.#dragState.endDrag();\n }\n });\n }\n\n /**\n * Get the parent droppable ID.\n */\n #getParentDroppableId(): string | null {\n const groupName = this.#effectiveGroup();\n if (!groupName) {\n return null;\n }\n\n const droppable = this.#positionCalculator.getDroppableParent(\n this.#elementRef.nativeElement,\n groupName,\n );\n\n return droppable ? this.#positionCalculator.getDroppableId(droppable) : null;\n }\n}\n","import {\n Directive,\n ElementRef,\n inject,\n input,\n NgZone,\n OnDestroy,\n OnInit,\n signal,\n} from '@angular/core';\nimport { VDND_SCROLL_CONTAINER, VdndScrollContainer } from '../tokens/scroll-container.token';\nimport { AutoScrollConfig, AutoScrollService } from '../services/auto-scroll.service';\nimport {\n bindRafThrottledScrollTopSignal,\n bindResizeObserverHeightSignal,\n} from '../utils/dom-signal-bindings';\nimport { createAutoScrollRegistration } from '../utils/auto-scroll-registration';\n\n/**\n * Directive that marks an element as a scrollable container for virtual scrolling.\n *\n * Apply this directive to any scrollable element (with `overflow: auto` or `overflow: scroll`)\n * that contains a `*vdndVirtualFor` directive. The virtual scroll will use this element\n * as its scroll container.\n *\n * @example\n * Basic usage with a custom scroll container:\n * ```html\n * <div vdndScrollable style=\"overflow: auto; height: 400px;\">\n * <ng-container *vdndVirtualFor=\"let item of items(); itemHeight: 50; trackBy: trackById\">\n * <div>{{ item.name }}</div>\n * </ng-container>\n * </div>\n * ```\n *\n * @example\n * With Ionic ion-content:\n * ```html\n * <ion-content vdndScrollable class=\"ion-content-scroll-host\">\n * <ng-container *vdndVirtualFor=\"let item of items(); itemHeight: 50; trackBy: trackById\">\n * <div>{{ item.name }}</div>\n * </ng-container>\n * </ion-content>\n * ```\n *\n * @example\n * With auto-scroll configuration:\n * ```html\n * <div vdndScrollable\n * [autoScrollEnabled]=\"true\"\n * [autoScrollConfig]=\"{ threshold: 80, maxSpeed: 20 }\"\n * style=\"overflow: auto; height: 400px;\">\n * ...\n * </div>\n * ```\n */\n@Directive({\n selector: '[vdndScrollable]',\n providers: [{ provide: VDND_SCROLL_CONTAINER, useExisting: ScrollableDirective }],\n host: {\n class: 'vdnd-scrollable',\n '[style.overflow-anchor]': '\"none\"',\n },\n})\nexport class ScrollableDirective implements VdndScrollContainer, OnInit, OnDestroy {\n readonly #elementRef = inject(ElementRef<HTMLElement>);\n readonly #ngZone = inject(NgZone);\n readonly #autoScrollService = inject(AutoScrollService);\n\n /** Current scroll position (reactive) */\n readonly #scrollTop = signal(0);\n\n /** Measured container height (reactive) */\n readonly #containerHeight = signal(0);\n\n /** Cleanup function for scroll listener */\n #scrollCleanup: (() => void) | null = null;\n #resizeCleanup: (() => void) | null = null;\n\n /** Generated ID for auto-scroll registration */\n #generatedScrollId = `vdnd-scroll-${Math.random().toString(36).slice(2, 9)}`;\n\n // ========== Inputs ==========\n\n /** Unique ID for this scroll container (used for auto-scroll registration) */\n scrollContainerId = input<string>();\n\n /** Whether auto-scroll is enabled when dragging near edges */\n autoScrollEnabled = input<boolean>(true);\n\n /** Auto-scroll configuration */\n autoScrollConfig = input<Partial<AutoScrollConfig>>({});\n\n // ========== VdndScrollContainer Implementation ==========\n\n constructor() {\n createAutoScrollRegistration({\n autoScrollService: this.#autoScrollService,\n getElement: () => this.nativeElement,\n getId: () => this.scrollContainerId() ?? this.#generatedScrollId,\n enabled: () => this.autoScrollEnabled(),\n config: () => this.autoScrollConfig(),\n });\n }\n\n get nativeElement(): HTMLElement {\n return this.#elementRef.nativeElement;\n }\n\n scrollTop(): number {\n return this.#scrollTop();\n }\n\n scrollTo(options: ScrollToOptions): void {\n this.nativeElement.scrollTo(options);\n }\n\n // ========== Additional API ==========\n\n /** Get the measured container height */\n containerHeight(): number {\n return this.#containerHeight();\n }\n\n /** Scroll by a delta amount */\n scrollBy(delta: number): void {\n const newPosition = Math.max(\n 0,\n Math.min(\n this.scrollTop() + delta,\n this.nativeElement.scrollHeight - this.nativeElement.clientHeight,\n ),\n );\n this.scrollTo({ top: newPosition });\n }\n\n // ========== Lifecycle ==========\n\n ngOnInit(): void {\n this.#setupScrollListener();\n this.#setupResizeObserver();\n }\n\n ngOnDestroy(): void {\n this.#scrollCleanup?.();\n this.#resizeCleanup?.();\n }\n\n // ========== Private Methods ==========\n\n /** Minimum scroll delta (px) to trigger signal update */\n readonly #scrollThreshold = 5;\n\n #setupScrollListener(): void {\n this.#scrollCleanup = bindRafThrottledScrollTopSignal({\n element: this.nativeElement,\n ngZone: this.#ngZone,\n scrollTop: this.#scrollTop,\n thresholdPx: this.#scrollThreshold,\n });\n }\n\n #setupResizeObserver(): void {\n this.#resizeCleanup = bindResizeObserverHeightSignal({\n element: this.nativeElement,\n ngZone: this.#ngZone,\n height: this.#containerHeight,\n minDeltaPx: 1,\n });\n }\n}\n","import {\n computed,\n Directive,\n effect,\n ElementRef,\n EmbeddedViewRef,\n inject,\n Injector,\n input,\n isDevMode,\n NgZone,\n OnDestroy,\n OnInit,\n PLATFORM_ID,\n TemplateRef,\n untracked,\n ViewContainerRef,\n} from '@angular/core';\nimport { isPlatformBrowser } from '@angular/common';\nimport { VDND_SCROLL_CONTAINER } from '../tokens/scroll-container.token';\nimport { VDND_OFFSET_ROWS_VIEWPORT, VDND_VIRTUAL_VIEWPORT } from '../tokens/virtual-viewport.token';\nimport { DragStateService } from '../services/drag-state.service';\nimport { DragIndexCalculatorService } from '../services/drag-index-calculator.service';\nimport { DroppableDirective } from './droppable.directive';\nimport type { VirtualScrollStrategy } from '../models/virtual-scroll-strategy';\nimport { FixedHeightStrategy } from '../strategies/fixed-height.strategy';\nimport { DynamicHeightStrategy } from '../strategies/dynamic-height.strategy';\nimport { setStrategyItems } from '../strategies/strategy-items';\nimport { VDND_ANIMATION_CONFIG } from '../tokens/animation-config.token';\nimport { ShiftAnimationEntry, ShiftAnimator } from '../utils/shift-animator';\nimport { revealDropTargetIn } from '../utils/drop-animator';\n\n/**\n * Context provided to the template for each virtual item.\n */\nexport interface VirtualForContext<T> {\n /** The item data (also available as implicit context) */\n $implicit: T;\n /** The item's index in the original array */\n index: number;\n /** Whether this is the first visible item */\n first: boolean;\n /** Whether this is the last visible item */\n last: boolean;\n /** Count of total items */\n count: number;\n}\n\n/** Render-queue key of the placeholder entry */\nconst PLACEHOLDER_KEY = '__placeholder__';\n\n/**\n * Represents an item entry in the render queue for virtual scrolling.\n * @internal\n */\ninterface RenderEntry<T> {\n type: 'item' | 'placeholder';\n key: unknown;\n context: VirtualForContext<T> | null;\n visualIndex: number;\n}\n\n/**\n * A structural directive for virtual scrolling within custom scroll containers.\n * Provides maximum flexibility for advanced use cases where the component wrapper\n * is not suitable.\n *\n * The directive must be placed inside a container marked with the `vdndScrollable`\n * directive, which provides the scroll container context via dependency injection.\n *\n * Placeholders are handled automatically by the parent component (vdnd-virtual-scroll\n * or vdnd-virtual-content) - consumers just render their items normally.\n *\n * @example\n * Inside a viewport component (itemHeight and droppableId inherited automatically):\n * ```html\n * <vdnd-virtual-viewport [itemHeight]=\"50\" style=\"height: 400px\">\n * <ng-container *vdndVirtualFor=\"let item of items(); trackBy: trackById\">\n * <div class=\"item\">{{ item.name }}</div>\n * </ng-container>\n * </vdnd-virtual-viewport>\n * ```\n *\n * @example\n * Standalone usage (itemHeight required):\n * ```html\n * <div vdndScrollable style=\"overflow: auto; height: 400px\">\n * <ng-container *vdndVirtualFor=\"let item of items(); itemHeight: 50; trackBy: trackById\">\n * <div class=\"item\">{{ item.name }}</div>\n * </ng-container>\n * </div>\n * ```\n */\n@Directive({\n selector: '[vdndVirtualFor][vdndVirtualForOf]',\n})\nexport class VirtualForDirective<T> implements OnInit, OnDestroy {\n readonly #templateRef = inject(TemplateRef<VirtualForContext<T>>);\n readonly #viewContainer = inject(ViewContainerRef);\n readonly #elementRef = inject(ElementRef<Comment>);\n readonly #scrollContainer = inject(VDND_SCROLL_CONTAINER);\n readonly #injector = inject(Injector);\n readonly #ngZone = inject(NgZone);\n readonly #isBrowser = isPlatformBrowser(inject(PLATFORM_ID));\n readonly #dragState = inject(DragStateService);\n readonly #dragIndexCalculator = inject(DragIndexCalculatorService);\n\n /**\n * Optional viewport component that provides wrapper-based positioning.\n * When inside a viewport, items are positioned via the wrapper's transform,\n * so we skip individual absolute positioning.\n */\n readonly #viewport = inject(VDND_VIRTUAL_VIEWPORT, { optional: true });\n\n /** A vdnd-virtual-viewport, whose rows start contentOffset px down (see #rowsScrollTop) */\n readonly #offsetRowsViewport = inject(VDND_OFFSET_ROWS_VIEWPORT, { optional: true });\n\n /**\n * Optional parent droppable directive.\n * When present, droppableId is inherited automatically.\n */\n readonly #droppable = inject(DroppableDirective, { optional: true });\n\n /** Slides items displaced by the placeholder (only when VDND_ANIMATION_CONFIG is provided) */\n readonly #shiftAnimator = this.#createShiftAnimator();\n\n /** Whether we're inside a viewport component (use wrapper positioning) */\n readonly #useViewportPositioning = this.#viewport !== null;\n\n /** Pool of views for reuse */\n readonly #viewPool: EmbeddedViewRef<VirtualForContext<T>>[] = [];\n\n /** Currently active views keyed by their track-by value */\n readonly #activeViews = new Map<unknown, EmbeddedViewRef<VirtualForContext<T>>>();\n\n /** Single spacer element for scroll height */\n #spacer: HTMLDivElement | null = null;\n\n /** Placeholder element for drag operations */\n #placeholder: HTMLDivElement | null = null;\n\n /** Whether placeholder is currently in the DOM */\n #placeholderInDom = false;\n\n /** ResizeObserver for dynamic height measurement */\n #resizeObserver: ResizeObserver | null = null;\n\n /** Map from observed HTMLElement to its trackBy key (reset with each new observer) */\n #observedElements = new WeakMap<HTMLElement, unknown>();\n\n // ========== Inputs ==========\n\n /** The array of items to iterate over */\n vdndVirtualForOf = input.required<T[]>();\n\n /**\n * Height of each item in pixels (used as estimate in dynamic mode).\n * Optional when inside a viewport component — inherited from the viewport's strategy.\n */\n vdndVirtualForItemHeight = input<number>();\n\n /** Track-by function for efficient updates */\n vdndVirtualForTrackBy = input.required<(index: number, item: T) => unknown>();\n\n /** Number of items to render outside the visible area */\n vdndVirtualForOverscan = input<number>(3);\n\n /**\n * ID of the droppable this directive belongs to.\n * Required for placeholder positioning during drag operations.\n */\n vdndVirtualForDroppableId = input<string>();\n\n /**\n * Enable dynamic item height mode.\n * When true, items are auto-measured via ResizeObserver and `itemHeight`\n * serves as the initial estimate for unmeasured items.\n */\n vdndVirtualForDynamicItemHeight = input<boolean>(false);\n\n // ========== Resolved Values ==========\n\n /**\n * Effective droppable ID — uses explicit input or inherits from parent DroppableDirective.\n */\n readonly #effectiveDroppableId = computed(() => {\n return this.vdndVirtualForDroppableId() ?? this.#droppable?.vdndDroppable() ?? undefined;\n });\n\n // ========== Strategy ==========\n\n /**\n * The virtual scroll strategy.\n * If inside a viewport that has a strategy, use that. Otherwise create our own.\n */\n readonly #strategy = computed<VirtualScrollStrategy>(() => {\n // If viewport provides a strategy, use it (shared state for drag-drop)\n const viewportStrategy = this.#viewport?.strategy;\n if (viewportStrategy) return viewportStrategy;\n\n // Create our own strategy (standalone mode — itemHeight is required)\n const height = this.vdndVirtualForItemHeight();\n if (height === undefined) {\n if (isDevMode()) {\n console.warn(\n '[ngx-virtual-dnd] vdndVirtualFor requires itemHeight when not inside a viewport component ' +\n '(vdnd-virtual-viewport or vdnd-virtual-content). Falling back to 50px.',\n );\n }\n return new FixedHeightStrategy(50);\n }\n return this.vdndVirtualForDynamicItemHeight()\n ? new DynamicHeightStrategy(height)\n : new FixedHeightStrategy(height);\n });\n\n // ========== Placeholder Computed Values ==========\n\n /** Whether the placeholder should be shown in this container */\n readonly #shouldShowPlaceholder = computed(() => {\n const droppableId = this.#effectiveDroppableId();\n if (!droppableId) return false;\n if (!this.#dragState.isDragging()) return false;\n return this.#dragState.activeDroppableId() === droppableId;\n });\n\n /** The placeholder index when placeholder should be shown */\n readonly #placeholderIndex = computed(() => {\n if (!this.#shouldShowPlaceholder()) return -1;\n return this.#dragState.placeholderIndex() ?? -1;\n });\n\n // ========== Computed Values ==========\n\n /** First visible item index */\n readonly #firstVisibleIndex = computed(() => {\n const strategy = this.#strategy();\n // Read version to subscribe to dynamic height changes\n strategy.version();\n return strategy.getFirstVisibleIndex(this.#rowsScrollTop());\n });\n\n /**\n * How far the rows are scrolled. A vdnd-virtual-viewport's rows start contentOffset px down its\n * scroll area, but its scrollTop() is the raw position (scrollBy() relies on it), so subtract the\n * offset here. vdnd-virtual-content's scrollTop() already excludes its offset.\n */\n #rowsScrollTop(): number {\n const scrollTop = this.#scrollContainer.scrollTop();\n const viewport = this.#viewport;\n if (viewport === null || viewport !== this.#offsetRowsViewport) {\n return scrollTop;\n }\n return Math.max(0, scrollTop - viewport.contentOffset());\n }\n\n /** Number of visible items */\n readonly #visibleCount = computed(() => {\n const height = this.#scrollContainer.containerHeight();\n const strategy = this.#strategy();\n strategy.version();\n const startIndex = this.#firstVisibleIndex();\n return strategy.getVisibleCount(startIndex, height);\n });\n\n /** Range of items to render */\n readonly #renderRange = computed(() => {\n const first = this.#firstVisibleIndex();\n const visible = this.#visibleCount();\n const overscan = this.vdndVirtualForOverscan();\n const total = this.vdndVirtualForOf().length;\n\n const start = Math.max(0, first - overscan);\n const end = Math.min(total - 1, first + visible + overscan);\n\n return { start, end };\n });\n\n /**\n * Every item's track key, in order. Computed once per items change, and only when something\n * reads it: a dynamic-height strategy or a drag. A fixed-height strategy needs only the count.\n */\n readonly #itemKeys = computed(() => {\n const trackByFn = this.vdndVirtualForTrackBy();\n return this.vdndVirtualForOf().map((item, i) => trackByFn(i, item));\n });\n\n /**\n * Index of the dragged item in this list (-1 if not present or not dragging). The index where\n * the drag found its item is checked first: it spares a search of every track key.\n */\n readonly #draggedItemIndex = computed(() => {\n const draggedItem = this.#dragState.draggedItem();\n if (!draggedItem) return -1;\n\n const items = this.vdndVirtualForOf();\n const sourceIndex = this.#dragState.sourceIndex();\n if (sourceIndex !== null && sourceIndex >= 0 && sourceIndex < items.length) {\n const item = items[sourceIndex];\n if (\n this.vdndVirtualForTrackBy()(sourceIndex, item) === draggedItem.draggableId ||\n (draggedItem.data !== null && draggedItem.data !== undefined && item === draggedItem.data)\n ) {\n return sourceIndex;\n }\n }\n\n // The last item with the key, as an index map filled in order would give\n const byId = this.#itemKeys().lastIndexOf(draggedItem.draggableId);\n if (byId >= 0) {\n return byId;\n }\n\n const data = draggedItem.data as T | null | undefined;\n if (data !== null && data !== undefined) {\n return items.indexOf(data);\n }\n\n return -1;\n });\n\n constructor() {\n // Keep the strategy's items in sync. A fixed-height strategy needs only their count, which\n // spares computing every item's track key on each items change (each drop).\n effect(() => {\n setStrategyItems(this.#strategy(), this.vdndVirtualForOf().length, () => this.#itemKeys());\n });\n\n // Register strategy with drag index calculator for accurate position lookups\n effect((onCleanup) => {\n const droppableId = this.#effectiveDroppableId();\n const strategy = this.#strategy();\n if (droppableId) {\n this.#dragIndexCalculator.registerStrategy(droppableId, strategy);\n onCleanup(() => this.#dragIndexCalculator.unregisterStrategy(droppableId));\n }\n });\n\n // Set excluded index persistently during same-list drag.\n // This ensures ALL strategy methods (getTotalHeight, getOffsetForIndex, etc.)\n // correctly skip the hidden item — not just findIndexAtOffset.\n effect(() => {\n const strategy = this.#strategy();\n const droppableId = this.#effectiveDroppableId();\n const sourceDroppableId = this.#dragState.sourceDroppableId();\n const isDragging = this.#dragState.isDragging();\n\n const isSourceList =\n isDragging && droppableId !== undefined && droppableId === sourceDroppableId;\n // Only the source list looks for the dragged item (in all its keys)\n const draggedIndex = isSourceList ? this.#draggedItemIndex() : -1;\n\n if (draggedIndex >= 0) {\n strategy.setExcludedIndex(draggedIndex);\n } else {\n strategy.setExcludedIndex(null);\n }\n });\n\n // Measure item heights in dynamic height mode: the directive's own input, or the viewport's\n // strategy when inherited. Both can change at runtime, and the strategy is replaced when they\n // do, so this creates, replaces or removes the observer. A new observer reports every\n // rendered item, so a new strategy gets their heights.\n effect((onCleanup) => {\n // Read the strategy first so the effect tracks its replacement even when the input is on\n const strategy = this.#strategy();\n const measure =\n this.vdndVirtualForDynamicItemHeight() || strategy instanceof DynamicHeightStrategy;\n // No ResizeObserver during server rendering\n if (!measure || !this.#isBrowser) {\n return;\n }\n untracked(() => this.#startMeasuring());\n onCleanup(() => this.#stopMeasuring());\n });\n\n // React to changes and update views\n effect(() => {\n this.#updateViews();\n });\n }\n\n ngOnInit(): void {\n // Server rendering: there is no ResizeObserver, and elements added outside the template\n // (spacer, placeholder) would not match the client's DOM during hydration. The browser adds\n // the spacer on init, so the server markup lacks only the list's scroll height until then.\n if (!this.#isBrowser) {\n return;\n }\n\n // Only create spacer when NOT inside a viewport component\n // (viewport provides its own spacer and wrapper positioning)\n if (!this.#useViewportPositioning) {\n this.#updateSpacers();\n }\n\n // Create placeholder element for drag operations\n this.#createPlaceholder();\n }\n\n ngOnDestroy(): void {\n this.#viewPool.forEach((view) => view.destroy());\n this.#activeViews.forEach((view) => view.destroy());\n\n // Clean up spacer element (only if we created one)\n this.#spacer?.remove();\n\n // Clean up placeholder element\n this.#placeholder?.remove();\n\n // Clean up ResizeObserver\n this.#resizeObserver?.disconnect();\n\n this.#shiftAnimator?.cancelAll();\n }\n\n #createShiftAnimator(): ShiftAnimator | null {\n const config = inject(VDND_ANIMATION_CONFIG, { optional: true });\n if (!config) return null;\n return new ShiftAnimator({\n config,\n injector: this.#injector,\n getScrollElement: () => this.#scrollContainer.nativeElement,\n getEntries: () => this.#shiftAnimationEntries(),\n });\n }\n\n /** Rendered item root elements (keyed by trackBy key) plus the placeholder. */\n *#shiftAnimationEntries(): Iterable<ShiftAnimationEntry> {\n for (const [key, view] of this.#activeViews) {\n for (const node of view.rootNodes) {\n if (node instanceof HTMLElement) {\n yield [key, node];\n }\n }\n }\n if (this.#placeholder && this.#placeholderInDom) {\n yield [PLACEHOLDER_KEY, this.#placeholder];\n }\n }\n\n /**\n * Create the placeholder element for drag operations.\n */\n #createPlaceholder(): void {\n const placeholder = document.createElement('div');\n placeholder.className = 'vdnd-drag-placeholder vdnd-drag-placeholder-visible';\n placeholder.style.cssText = 'display: block; pointer-events: none;';\n this.#placeholder = placeholder;\n }\n\n /**\n * Set up spacer element for scroll height.\n */\n #updateSpacers(): void {\n // Create single spacer that maintains total scroll height\n const spacer = document.createElement('div');\n spacer.className = 'vdnd-virtual-for-spacer';\n spacer.style.cssText =\n 'position: absolute; top: 0; left: 0; width: 1px; visibility: hidden; pointer-events: none;';\n\n // Insert spacer before the directive's anchor comment\n const comment = this.#elementRef.nativeElement;\n comment.parentNode?.insertBefore(spacer, comment);\n\n this.#spacer = spacer;\n\n // Update spacer height reactively\n // Must pass injector since we're outside constructor\n effect(\n () => {\n const total = this.vdndVirtualForOf().length;\n const strategy = this.#strategy();\n strategy.version();\n\n // Single spacer with full content height\n spacer.style.height = `${strategy.getTotalHeight(total)}px`;\n },\n { injector: this.#injector },\n );\n }\n\n /** Create the ResizeObserver and observe the items already rendered. */\n #startMeasuring(): void {\n this.#setupResizeObserver();\n for (const [key, view] of this.#activeViews) {\n this.#observeViewElements(view, key);\n }\n }\n\n /** Disconnect the ResizeObserver and forget what it observed. */\n #stopMeasuring(): void {\n this.#resizeObserver?.disconnect();\n this.#resizeObserver = null;\n this.#observedElements = new WeakMap();\n }\n\n /**\n * Set up ResizeObserver for dynamic height measurement.\n */\n #setupResizeObserver(): void {\n this.#ngZone.runOutsideAngular(() => {\n this.#resizeObserver = new ResizeObserver((entries) => {\n const strategy = this.#strategy();\n for (const entry of entries) {\n const element = entry.target as HTMLElement;\n const key = this.#observedElements.get(element);\n if (key === undefined) continue;\n\n const height = entry.borderBoxSize?.[0]?.blockSize ?? element.offsetHeight;\n if (height > 0) {\n strategy.setMeasuredHeight(key, height);\n }\n }\n });\n });\n }\n\n /**\n * Observe an element's root nodes for height changes.\n */\n #observeViewElements(view: EmbeddedViewRef<VirtualForContext<T>>, key: unknown): void {\n if (!this.#resizeObserver) return;\n\n for (const node of view.rootNodes) {\n if (node instanceof HTMLElement) {\n const existingKey = this.#observedElements.get(node);\n if (Object.is(existingKey, key)) {\n continue;\n }\n if (existingKey !== undefined) {\n this.#resizeObserver.unobserve(node);\n }\n this.#observedElements.set(node, key);\n this.#resizeObserver.observe(node);\n }\n }\n }\n\n /**\n * Stop any shift animation on a view about to be pooled — a recycled view must not\n * carry an in-flight offset over to the item it renders next.\n */\n #cancelShiftAnimation(view: EmbeddedViewRef<VirtualForContext<T>>): void {\n if (!this.#shiftAnimator) return;\n\n for (const node of view.rootNodes) {\n if (node instanceof HTMLElement) {\n this.#shiftAnimator.cancel(node);\n }\n }\n }\n\n /**\n * Stop observing an element's root nodes.\n */\n #unobserveViewElements(view: EmbeddedViewRef<VirtualForContext<T>>): void {\n if (!this.#resizeObserver) return;\n\n for (const node of view.rootNodes) {\n if (node instanceof HTMLElement) {\n this.#observedElements.delete(node);\n this.#resizeObserver.unobserve(node);\n }\n }\n }\n\n /**\n * Update the rendered views with true view recycling.\n * Views are kept in the DOM and have their context updated in place when possible.\n */\n #updateViews(): void {\n const items = this.vdndVirtualForOf();\n const { start, end } = this.#renderRange();\n const strategy = this.#strategy();\n strategy.version();\n const placeholderIndex = this.#placeholderIndex();\n const showPlaceholder = this.#shouldShowPlaceholder();\n const droppableId = this.#effectiveDroppableId();\n const sourceDroppableId = this.#dragState.sourceDroppableId();\n const isSourceList = droppableId ? droppableId === sourceDroppableId : true;\n // Only the source list keeps the dragged item rendered, so only it looks for the item\n const draggedIndex =\n this.#dragState.isDragging() && isSourceList ? this.#draggedItemIndex() : -1;\n const shouldKeepDragged = draggedIndex >= 0 && draggedIndex < items.length;\n\n // Snapshot positions before the DOM changes so displaced items can slide\n this.#shiftAnimator?.beforeUpdate(this.#dragState.isDragging(), placeholderIndex);\n\n // Notify viewport of render start index for wrapper positioning\n this.#notifyViewportRenderStart(start);\n\n // 1. Build the list of items to render\n const itemsToRender = this.#calculateItemsToRender({\n items,\n start,\n end,\n showPlaceholder,\n placeholderIndex,\n shouldKeepDragged,\n draggedIndex,\n });\n\n // 2. Reconcile views with the DOM\n const placeholderDomPosition = this.#reconcileViews(itemsToRender, showPlaceholder, strategy);\n\n // 3. Position placeholder in DOM\n this.#positionPlaceholder(showPlaceholder, placeholderDomPosition, strategy, placeholderIndex);\n\n // 4. Trim view pool to prevent memory bloat\n this.#trimViewPool();\n }\n\n /**\n * Notify viewport of render start index for wrapper positioning.\n * With persistent excluded index, getOffsetForIndex already accounts for hidden items.\n */\n #notifyViewportRenderStart(start: number): void {\n if (!this.#useViewportPositioning) return;\n this.#viewport?.setRenderStartIndex(start);\n }\n\n /**\n * Calculate the list of items to render, including placeholder positioning\n * and keeping the dragged item alive when scrolled out of range.\n */\n #calculateItemsToRender(params: {\n items: T[];\n start: number;\n end: number;\n showPlaceholder: boolean;\n placeholderIndex: number;\n shouldKeepDragged: boolean;\n draggedIndex: number;\n }): RenderEntry<T>[] {\n const {\n items,\n start,\n end,\n showPlaceholder,\n placeholderIndex,\n shouldKeepDragged,\n draggedIndex,\n } = params;\n const trackByFn = this.vdndVirtualForTrackBy();\n const itemsToRender: RenderEntry<T>[] = [];\n\n // Track placeholder insertion with a flag instead of re-scanning itemsToRender\n // with `.some()` on every iteration (which made the build loop O(n²)).\n let placeholderInserted = false;\n\n // Build render list for visible range\n for (let i = start; i <= end && i < items.length; i++) {\n // Insert placeholder before item at placeholderIndex\n if (showPlaceholder && placeholderIndex === i && !placeholderInserted) {\n itemsToRender.push({\n type: 'placeholder',\n key: PLACEHOLDER_KEY,\n context: null,\n visualIndex: placeholderIndex,\n });\n placeholderInserted = true;\n }\n\n const item = items[i];\n itemsToRender.push({\n type: 'item',\n key: trackByFn(i, item),\n context: {\n $implicit: item,\n index: i,\n first: i === start,\n last: i === end || i === items.length - 1,\n count: items.length,\n },\n visualIndex: i,\n });\n }\n\n // Add placeholder at end if needed\n if (showPlaceholder && placeholderIndex >= items.length && !placeholderInserted) {\n itemsToRender.push({\n type: 'placeholder',\n key: PLACEHOLDER_KEY,\n context: null,\n visualIndex: placeholderIndex,\n });\n }\n\n // Keep dragged item view alive when scrolled out of range\n if (shouldKeepDragged && (draggedIndex < start || draggedIndex > end)) {\n const draggedItem = items[draggedIndex];\n const draggedKey = trackByFn(draggedIndex, draggedItem);\n const alreadyRendered = itemsToRender.some(\n (entry) => entry.type === 'item' && entry.key === draggedKey,\n );\n if (!alreadyRendered) {\n itemsToRender.push({\n type: 'item',\n key: draggedKey,\n context: {\n $implicit: draggedItem,\n index: draggedIndex,\n first: draggedIndex === 0,\n last: draggedIndex === items.length - 1,\n count: items.length,\n },\n visualIndex: draggedIndex,\n });\n }\n }\n\n return itemsToRender;\n }\n\n /**\n * Reconcile views with the calculated items to render.\n * Moves unused views to pool, updates existing views, creates new views as needed.\n * Returns the DOM position where placeholder should be inserted.\n */\n #reconcileViews(\n itemsToRender: RenderEntry<T>[],\n showPlaceholder: boolean,\n strategy: VirtualScrollStrategy,\n ): number {\n // Determine which keys we need\n const neededKeys = new Set(\n itemsToRender.filter((r) => r.type === 'item').map((item) => item.key),\n );\n\n // Move unused views to pool\n for (const [key, view] of this.#activeViews) {\n if (!neededKeys.has(key)) {\n this.#activeViews.delete(key);\n this.#poolView(view);\n }\n }\n\n // Remove placeholder from DOM if not needed\n if (!showPlaceholder && this.#placeholderInDom && this.#placeholder) {\n this.#placeholder.remove();\n this.#placeholderInDom = false;\n }\n\n // Process items and track placeholder position\n let viewContainerIndex = 0;\n let placeholderDomPosition = -1;\n const renderedKeys = new Set<unknown>();\n const changedViews: EmbeddedViewRef<VirtualForContext<T>>[] = [];\n\n for (const entry of itemsToRender) {\n if (entry.type === 'placeholder') {\n placeholderDomPosition = viewContainerIndex;\n continue;\n }\n\n if (renderedKeys.has(entry.key)) {\n this.#warnDuplicateTrackByKey(entry.key);\n continue;\n }\n renderedKeys.add(entry.key);\n\n const view = this.#getOrCreateView(entry.key, entry.context!, changedViews);\n\n // Ensure view is at correct position in ViewContainerRef\n const currentIndex = this.#viewContainer.indexOf(view);\n if (currentIndex !== viewContainerIndex) {\n const targetIndex = this.#getSafeViewContainerIndex(currentIndex, viewContainerIndex);\n if (currentIndex >= 0) {\n if (currentIndex !== targetIndex) {\n this.#viewContainer.move(view, targetIndex);\n }\n } else {\n this.#viewContainer.insert(view, targetIndex);\n }\n }\n\n // Apply absolute positioning when not using viewport wrapper\n if (!this.#useViewportPositioning) {\n const offset = strategy.getOffsetForIndex(entry.visualIndex);\n this.#applyAbsolutePositioning(view, offset);\n }\n\n // Observe for dynamic height measurement\n if (this.#resizeObserver) {\n this.#observeViewElements(view, entry.key);\n }\n\n viewContainerIndex++;\n }\n\n this.#renderChangedViews(changedViews);\n\n return placeholderDomPosition;\n }\n\n /**\n * Take a row's view out of the container and pool it. It keeps its element, so its shift\n * animation is cancelled (the item it renders next must not slide from this one's position),\n * and a drop animation that hides it shows it again.\n */\n #poolView(view: EmbeddedViewRef<VirtualForContext<T>>): void {\n const index = this.#viewContainer.indexOf(view);\n if (index >= 0) {\n this.#viewContainer.detach(index);\n }\n this.#unobserveViewElements(view);\n // A leave animation (`animate.leave`) keeps the row in the DOM, and Angular removes it when\n // the animation ends: in the row of another item by then, if the view were reused. A row\n // whose element is dragged (its draggable ID is not its track key) is destroyed too, which\n // cancels the drag instead of handing it to another item.\n const draggedElement = this.#dragState.draggedItem()?.element;\n if (\n view.rootNodes.some(\n (node: Node) =>\n node.parentNode !== null || (!!draggedElement && node.contains(draggedElement)),\n )\n ) {\n view.destroy();\n return;\n }\n this.#cancelShiftAnimation(view);\n revealDropTargetIn(view.rootNodes);\n this.#viewPool.push(view);\n }\n\n /**\n * Clamp target indices for move/insert to avoid out-of-range operations when\n * reconciliation is given invalid duplicate keys or transiently inconsistent view state.\n */\n #getSafeViewContainerIndex(currentIndex: number, requestedIndex: number): number {\n const length = this.#viewContainer.length;\n\n if (currentIndex >= 0) {\n if (length <= 1) return 0;\n return Math.min(requestedIndex, length - 1);\n }\n\n return Math.min(requestedIndex, length);\n }\n\n /**\n * Duplicate trackBy keys cannot be reconciled to distinct views.\n * Warn in dev mode and skip duplicates to prevent container corruption.\n */\n #warnDuplicateTrackByKey(key: unknown): void {\n if (isDevMode()) {\n console.warn(\n `[ngx-virtual-dnd] Duplicate trackBy key detected in vdndVirtualFor: ${String(key)}. ` +\n 'Skipping duplicate item to avoid view reconciliation errors.',\n );\n }\n }\n\n /**\n * Get an existing view or create/recycle one from the pool.\n * Adds the view to `changedViews` when it needs rendering: new, taken from the pool, or with a\n * changed context.\n */\n #getOrCreateView(\n key: unknown,\n context: VirtualForContext<T>,\n changedViews: EmbeddedViewRef<VirtualForContext<T>>[],\n ): EmbeddedViewRef<VirtualForContext<T>> {\n const activeView = this.#activeViews.get(key);\n let view = activeView ?? this.#viewPool.pop();\n\n if (view) {\n // A pooled view was detached, so change detection skipped it: render it even when it\n // comes back with the same context, as what its template shows may have changed since\n if (this.#updateContext(view.context, context) || !activeView) {\n changedViews.push(view);\n }\n } else {\n view = this.#templateRef.createEmbeddedView(context);\n changedViews.push(view);\n }\n this.#activeViews.set(key, view);\n\n return view;\n }\n\n /** Copy the fields of `next` into `context`. Returns whether any of them changed. */\n #updateContext(context: VirtualForContext<T>, next: VirtualForContext<T>): boolean {\n if (\n Object.is(context.$implicit, next.$implicit) &&\n context.index === next.index &&\n context.first === next.first &&\n context.last === next.last &&\n context.count === next.count\n ) {\n return false;\n }\n context.$implicit = next.$implicit;\n context.index = next.index;\n context.first = next.first;\n context.last = next.last;\n context.count = next.count;\n return true;\n }\n\n /**\n * Render the views whose context changed, and only those. `markForCheck()` would mark every\n * ancestor view up to the root as well, re-rendering all of them (and every row of the list)\n * on each scroll step. Untracked, so the rows' signal reads do not become this effect's\n * dependencies.\n */\n #renderChangedViews(changedViews: EmbeddedViewRef<VirtualForContext<T>>[]): void {\n if (changedViews.length === 0) return;\n untracked(() => {\n for (const view of changedViews) {\n if (!view.destroyed) {\n view.detectChanges();\n }\n }\n });\n }\n\n /**\n * Apply absolute positioning styles to a view's root nodes.\n */\n #applyAbsolutePositioning(view: EmbeddedViewRef<VirtualForContext<T>>, topOffset: number): void {\n for (const node of view.rootNodes) {\n if (node instanceof HTMLElement) {\n node.style.position = 'absolute';\n node.style.top = `${topOffset}px`;\n node.style.left = '0';\n node.style.right = '0';\n }\n }\n }\n\n /**\n * Position the placeholder element in the DOM at the correct index.\n */\n #positionPlaceholder(\n showPlaceholder: boolean,\n placeholderDomPosition: number,\n strategy: VirtualScrollStrategy,\n placeholderIndex: number,\n ): void {\n if (!showPlaceholder || !this.#placeholder || placeholderDomPosition < 0) {\n return;\n }\n\n // Use the dragged item's height if available, otherwise use strategy height\n const draggedItemHeight = this.#dragState.draggedItem()?.height;\n const height = draggedItemHeight ?? strategy.getItemHeight(placeholderIndex);\n this.#placeholder.style.height = `${height}px`;\n\n const container = this.#viewContainer.element.nativeElement.parentElement;\n if (!container) return;\n\n // The placeholder goes immediately before the item view at placeholderDomPosition\n // (the reconcile pass counts item views only, so this index maps directly to a\n // ViewContainerRef view). Reading the reference node from that view avoids\n // re-querying and filtering container.children on every placeholder move.\n const insertBeforeEl = this.#getViewReferenceNode(placeholderDomPosition);\n\n if (!this.#placeholderInDom) {\n // First insertion\n if (insertBeforeEl) {\n container.insertBefore(this.#placeholder, insertBeforeEl);\n } else {\n container.appendChild(this.#placeholder);\n }\n this.#placeholderInDom = true;\n } else {\n // Move to correct position if needed\n const currentNextSibling = this.#placeholder.nextElementSibling;\n if (insertBeforeEl !== currentNextSibling) {\n if (insertBeforeEl) {\n container.insertBefore(this.#placeholder, insertBeforeEl);\n } else {\n container.appendChild(this.#placeholder);\n }\n }\n }\n }\n\n /**\n * Resolve the DOM node the placeholder should be inserted before, given the\n * item-view index produced by the reconcile pass. Returns null when the index\n * is past the last view (placeholder belongs at the end → append).\n */\n #getViewReferenceNode(viewIndex: number): Element | null {\n if (viewIndex < 0 || viewIndex >= this.#viewContainer.length) {\n return null;\n }\n const view = this.#viewContainer.get(viewIndex) as\n | EmbeddedViewRef<VirtualForContext<T>>\n | null\n | undefined;\n if (!view) {\n return null;\n }\n for (const node of view.rootNodes) {\n if (node instanceof HTMLElement) {\n return node;\n }\n }\n return null;\n }\n\n /**\n * Trim the view pool to prevent memory bloat, keeping a reasonable buffer.\n */\n #trimViewPool(): void {\n const maxPoolSize = 10;\n while (this.#viewPool.length > maxPoolSize) {\n const view = this.#viewPool.pop();\n view?.destroy();\n }\n }\n\n /**\n * Static method for Angular's structural directive microsyntax.\n */\n static ngTemplateContextGuard<T>(\n _dir: VirtualForDirective<T>,\n _ctx: unknown,\n ): _ctx is VirtualForContext<T> {\n return true;\n }\n}\n","import { isDevMode, untracked, type WritableSignal } from '@angular/core';\nimport { DropEvent } from '../models/drag-drop.models';\n\n/**\n * Moves an item between signal-based lists based on a drop event.\n * Handles both same-list reordering and cross-list moves.\n *\n * @example\n * ```typescript\n * // In your component:\n * readonly list1 = signal<Item[]>([...]);\n * readonly list2 = signal<Item[]>([...]);\n *\n * onDrop(event: DropEvent): void {\n * moveItem(event, {\n * 'list-1': this.list1,\n * 'list-2': this.list2,\n * });\n * }\n * ```\n *\n * @param event The drop event from the droppable directive\n * @param lists A map of droppable IDs to their corresponding WritableSignal arrays\n */\nexport function moveItem<T>(event: DropEvent, lists: Record<string, WritableSignal<T[]>>): void {\n const sourceList = lists[event.source.droppableId];\n const destList = lists[event.destination.droppableId];\n\n if (!sourceList || !destList) {\n if (isDevMode()) {\n console.warn(\n `[ngx-virtual-dnd] [moveItem] Could not find list for droppable \"${event.source.droppableId}\" or \"${event.destination.droppableId}\"`,\n );\n }\n return;\n }\n\n const sourceIndex = event.source.index;\n const destIndex = event.destination.index;\n\n // Same list reorder\n if (event.source.droppableId === event.destination.droppableId) {\n reorderItems(event, sourceList);\n return;\n }\n\n // Cross-list move. Read untracked, as in reorderItems: an effect that applies the drop must\n // not depend on the lists it changes.\n const item = untracked(sourceList)[sourceIndex];\n\n if (item === undefined) {\n if (isDevMode()) {\n console.warn(`[ngx-virtual-dnd] [moveItem] Could not find item at index ${sourceIndex}`);\n }\n return;\n }\n\n // Remove from source\n sourceList.update((items) => {\n const newItems = [...items];\n newItems.splice(sourceIndex, 1);\n return newItems;\n });\n\n // Insert at destination\n destList.update((items) => {\n const newItems = [...items];\n newItems.splice(destIndex, 0, item);\n return newItems;\n });\n}\n\n/**\n * Reorders items within a single signal-based list.\n *\n * @example\n * ```typescript\n * readonly items = signal<Item[]>([...]);\n *\n * onDrop(event: DropEvent): void {\n * reorderItems(event, this.items);\n * }\n * ```\n *\n * @param event The drop event from the droppable directive\n * @param list The WritableSignal array to reorder\n */\nexport function reorderItems<T>(event: DropEvent, list: WritableSignal<T[]>): void {\n const sourceIndex = event.source.index;\n const destIndex = event.destination.index;\n\n // No-op if same position\n if (sourceIndex === destIndex) {\n return;\n }\n\n // The list may have changed during the drag; never splice in a missing item as undefined.\n // Read untracked: from an effect, a tracked read would make the effect re-run on this reorder.\n if (untracked(list)[sourceIndex] === undefined) {\n if (isDevMode()) {\n console.warn(`[ngx-virtual-dnd] [reorderItems] Could not find item at index ${sourceIndex}`);\n }\n return;\n }\n\n list.update((items) => {\n const newItems = [...items];\n const [removed] = newItems.splice(sourceIndex, 1);\n\n // Note: destination.index from DropEvent is already adjusted for same-list\n // reordering by DroppableDirective.#handleDrop(), so we use it directly.\n newItems.splice(destIndex, 0, removed);\n return newItems;\n });\n}\n\n/**\n * Applies a move operation immutably, returning new array objects.\n * Useful for state management patterns that require immutable updates.\n *\n * @example\n * ```typescript\n * onDrop(event: DropEvent): void {\n * const { list1, list2 } = applyMove(event, {\n * 'list-1': this.list1,\n * 'list-2': this.list2,\n * });\n * // Use the returned arrays with your state management\n * }\n * ```\n *\n * @param event The drop event from the droppable directive\n * @param lists A map of droppable IDs to their corresponding arrays\n * @returns A new object with the same keys but updated arrays\n */\nexport function applyMove<T>(event: DropEvent, lists: Record<string, T[]>): Record<string, T[]> {\n const result = { ...lists };\n const sourceKey = event.source.droppableId;\n const destKey = event.destination.droppableId;\n const sourceIndex = event.source.index;\n const destIndex = event.destination.index;\n\n const sourceItems = [...(lists[sourceKey] ?? [])];\n const item = sourceItems[sourceIndex];\n\n if (item === undefined) {\n return result;\n }\n\n // Same list reorder\n // Note: destination.index from DropEvent is already adjusted for same-list\n // reordering by DroppableDirective.#handleDrop(), so we use it directly.\n if (sourceKey === destKey) {\n const [removed] = sourceItems.splice(sourceIndex, 1);\n sourceItems.splice(destIndex, 0, removed);\n result[sourceKey] = sourceItems;\n return result;\n }\n\n // Cross-list move\n const destItems = [...(lists[destKey] ?? [])];\n sourceItems.splice(sourceIndex, 1);\n destItems.splice(destIndex, 0, item);\n\n result[sourceKey] = sourceItems;\n result[destKey] = destItems;\n\n return result;\n}\n\n/**\n * Checks if a drop event represents a no-op (item dropped in its original position).\n * Useful for skipping unnecessary state updates.\n *\n * @example\n * ```typescript\n * onDrop(event: DropEvent): void {\n * if (isNoOpDrop(event)) {\n * return; // No action needed\n * }\n * moveItem(event, this.lists);\n * }\n * ```\n *\n * @param event The drop event to check\n * @returns true if the drop would result in no change\n */\nexport function isNoOpDrop(event: DropEvent): boolean {\n return (\n event.source.droppableId === event.destination.droppableId &&\n event.source.index === event.destination.index\n );\n}\n\n/**\n * Creates a new list with the item inserted at the specified index.\n * Low-level utility for custom implementations.\n *\n * @param list The source array\n * @param item The item to insert\n * @param index The index to insert at\n * @returns A new array with the item inserted\n */\nexport function insertAt<T>(list: T[], item: T, index: number): T[] {\n const result = [...list];\n result.splice(index, 0, item);\n return result;\n}\n\n/**\n * Creates a new list with the item at the specified index removed.\n * Low-level utility for custom implementations.\n *\n * @param list The source array\n * @param index The index to remove\n * @returns A new array with the item removed\n */\nexport function removeAt<T>(list: T[], index: number): T[] {\n const result = [...list];\n result.splice(index, 1);\n return result;\n}\n","// Models\nexport * from './models/drag-drop.models';\nexport type { VirtualScrollStrategy } from './models/virtual-scroll-strategy';\n\n// Strategies\nexport { FixedHeightStrategy } from './strategies/fixed-height.strategy';\nexport { DynamicHeightStrategy } from './strategies/dynamic-height.strategy';\n\n// Tokens\nexport { VDND_SCROLL_CONTAINER } from './tokens/scroll-container.token';\nexport type { VdndScrollContainer } from './tokens/scroll-container.token';\nexport { VDND_VIRTUAL_VIEWPORT } from './tokens/virtual-viewport.token';\nexport type { VdndVirtualViewport } from './tokens/virtual-viewport.token';\nexport { VDND_ANIMATION_CONFIG } from './tokens/animation-config.token';\nexport type { VdndAnimationConfig } from './tokens/animation-config.token';\n\n// Services\nexport { DragStateService } from './services/drag-state.service';\nexport { PositionCalculatorService } from './services/position-calculator.service';\nexport { AutoScrollService } from './services/auto-scroll.service';\nexport type { AutoScrollConfig } from './services/auto-scroll.service';\nexport { ElementCloneService } from './services/element-clone.service';\nexport { KeyboardDragService } from './services/keyboard-drag.service';\nexport { OverlayContainerService } from './services/overlay-container.service';\n\n// Components\nexport { VirtualScrollContainerComponent } from './components/virtual-scroll-container.component';\nexport type { VirtualScrollItemContext } from './components/virtual-scroll-container.component';\nexport { DragPreviewComponent } from './components/drag-preview.component';\nexport type { DragPreviewContext } from './components/drag-preview.component';\nexport { PlaceholderComponent } from './components/placeholder.component';\nexport type { PlaceholderContext } from './components/placeholder.component';\nexport { DragPlaceholderComponent } from './components/drag-placeholder.component';\nexport { VirtualSortableListComponent } from './components/virtual-sortable-list.component';\nexport { VirtualViewportComponent } from './components/virtual-viewport.component';\nexport { VirtualContentComponent } from './components/virtual-content.component';\n\n// Directives\nexport { DraggableDirective } from './directives/draggable.directive';\nexport { DroppableDirective } from './directives/droppable.directive';\nexport { DroppableGroupDirective, VDND_GROUP_TOKEN } from './directives/droppable-group.directive';\nexport type { VdndGroupContext } from './directives/droppable-group.directive';\nexport { ScrollableDirective } from './directives/scrollable.directive';\nexport { VirtualForDirective } from './directives/virtual-for.directive';\nexport type { VirtualForContext } from './directives/virtual-for.directive';\nexport { ContentHeaderDirective } from './directives/content-header.directive';\n\n// Utilities\nexport {\n moveItem,\n reorderItems,\n applyMove,\n isNoOpDrop,\n insertAt,\n removeAt,\n} from './utils/drop-helpers';\n","/*\n * Public API Surface of ngx-virtual-dnd\n */\n\nexport * from './lib/index';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
|