ngx-virtual-dnd 3.1.0 → 3.1.1

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ngx-virtual-dnd",
3
- "version": "3.1.0",
3
+ "version": "3.1.1",
4
4
  "description": "A performant drag-and-drop library for Angular that works seamlessly with virtual scrolling",
5
5
  "keywords": [
6
6
  "angular",
@@ -306,10 +306,12 @@ declare const VDND_VIRTUAL_VIEWPORT: InjectionToken<VdndVirtualViewport>;
306
306
  * Central service for managing drag-and-drop state.
307
307
  * Uses signals for reactive state management.
308
308
  *
309
- * Architecture: High-frequency fields (`cursorPosition`, `keyboardTargetIndex`)
310
- * are stored in dedicated signals, separate from the core state. This prevents
311
- * 60fps cursor updates from triggering re-evaluation of the 10+ computeds
312
- * that only depend on rarely-changing properties (isDragging, draggedItem, etc.).
309
+ * Architecture: High-frequency fields (`cursorPosition`, `keyboardTargetIndex`,
310
+ * `activeDroppableId`, `placeholderId`, `placeholderIndex`) are stored in dedicated
311
+ * signals, separate from the core state. This prevents 60fps cursor and
312
+ * placeholder updates from rebuilding the core state object or re-evaluating the
313
+ * 8+ computeds that only depend on rarely-changing properties (isDragging,
314
+ * draggedItem, etc.).
313
315
  */
314
316
  declare class DragStateService {
315
317
  #private;
@@ -365,6 +367,14 @@ declare class DragStateService {
365
367
  * Update just the placeholder position.
366
368
  */
367
369
  setPlaceholder(placeholderId: string | null): void;
370
+ /**
371
+ * Update only the placeholder signals without touching cursor position or active droppable.
372
+ *
373
+ * Used by the autoscroll scroll-only fast path: when a scroll fires, the cursor has not
374
+ * moved, so only the placeholder index needs recalculation. Skipping the cursor and
375
+ * active-droppable writes avoids spurious re-evaluation of computeds that read those signals.
376
+ */
377
+ updateScrollOnlyPlaceholder(placeholderId: string | null, placeholderIndex: number | null): void;
368
378
  /**
369
379
  * End the drag operation and reset state (normal drop).
370
380
  */
@@ -400,19 +410,52 @@ declare class DragStateService {
400
410
  */
401
411
  declare class PositionCalculatorService {
402
412
  #private;
413
+ /**
414
+ * Begin a drag session: snapshot the candidate droppables for `groupName` and
415
+ * their rects once, then watch for viewport changes (scroll/resize) that would
416
+ * invalidate those rects. While a session is active, `findDroppableAtPoint`
417
+ * runs as pure geometry against the cached rects instead of `elementFromPoint`.
418
+ *
419
+ * Safe to call repeatedly — a new call replaces any previous session.
420
+ */
421
+ beginDragSession(groupName: string): void;
422
+ /**
423
+ * End the current drag session and detach viewport listeners.
424
+ * Safe to call when no session is active.
425
+ */
426
+ endDragSession(): void;
427
+ /**
428
+ * Mark the cached droppable rects as stale so they are re-read on the next
429
+ * hit-test. Called explicitly from the autoscroll recalculation path, where the
430
+ * scroll event has not yet fired but the container has already moved.
431
+ */
432
+ invalidateDroppableRects(): void;
403
433
  /**
404
434
  * Find the droppable element at a given point.
405
435
  *
406
- * This works by temporarily hiding the dragged element, then using
407
- * document.elementFromPoint to find what's underneath the cursor.
436
+ * Uses pure geometric hit-testing against snapshotted droppable rects. When a
437
+ * drag session is active (see {@link beginDragSession}) the rects are cached and
438
+ * reused across frames; otherwise a one-shot DOM query is performed. The
439
+ * `draggedElement` parameter is retained for API compatibility but no longer
440
+ * needs to be hidden — geometry does not depend on cursor occlusion.
408
441
  *
409
442
  * @param x - Cursor X coordinate
410
443
  * @param y - Cursor Y coordinate
411
- * @param draggedElement - The element being dragged (will be temporarily hidden)
444
+ * @param _draggedElement - The element being dragged (unused; kept for compatibility)
412
445
  * @param groupName - The drag-and-drop group name to filter by
413
446
  * @returns The droppable element, or null if none found
414
447
  */
415
- findDroppableAtPoint(x: number, y: number, draggedElement: HTMLElement, groupName: string): HTMLElement | null;
448
+ findDroppableAtPoint(x: number, y: number, _draggedElement: HTMLElement, groupName: string): HTMLElement | null;
449
+ /**
450
+ * Look up a droppable element by its ID.
451
+ *
452
+ * When a drag session is active, searches the cached candidate list (O(n), avoids a DOM
453
+ * query). Falls back to `document.querySelector` when no session is active.
454
+ *
455
+ * Intended for the autoscroll scroll-only fast path, where the active droppable is already
456
+ * known and only the placeholder index needs recalculation.
457
+ */
458
+ getDroppableById(id: string): HTMLElement | null;
416
459
  /**
417
460
  * Find the draggable element at a given point.
418
461
  *
@@ -527,12 +570,14 @@ declare class AutoScrollService {
527
570
  unregisterContainer(id: string): void;
528
571
  /**
529
572
  * Start monitoring for auto-scroll.
530
- * Call this when a drag starts.
573
+ * Registers this service as a tick participant in DragSchedulerService.
574
+ * The scheduler drives the RAF loop; this service handles scroll logic each frame.
531
575
  * @param onScroll Optional callback to invoke when scrolling occurs (for placeholder recalculation)
532
576
  */
533
577
  startMonitoring(onScroll?: () => void): void;
534
578
  /**
535
579
  * Stop monitoring for auto-scroll.
580
+ * Removes this service from the scheduler's participant list.
536
581
  * Call this when a drag ends.
537
582
  */
538
583
  stopMonitoring(): void;
@@ -639,6 +684,19 @@ declare class KeyboardDragService {
639
684
  */
640
685
  declare class OverlayContainerService implements OnDestroy {
641
686
  #private;
687
+ /**
688
+ * Whether at least one mounted drag preview renders via a custom template.
689
+ *
690
+ * When true, DraggableDirective/KeyboardDragHandler skip the expensive
691
+ * drag-start element clone: the clone would never be shown because the
692
+ * template takes precedence (see DragPreviewComponent).
693
+ */
694
+ readonly hasTemplatePreview: _angular_core.Signal<boolean>;
695
+ /**
696
+ * Register (`active = true`) or unregister (`active = false`) a preview that
697
+ * renders via a custom template. Calls must be balanced per preview instance.
698
+ */
699
+ setTemplatePreviewActive(active: boolean): void;
642
700
  /**
643
701
  * Returns the shared overlay container element, lazily creating it on first access.
644
702
  * Returns `null` in non-browser environments (SSR).