@acorex/cdk 21.0.0-next.11 → 21.0.0-next.13

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.
@@ -16,6 +16,7 @@ declare class AXDragDirective implements OnInit, OnDestroy {
16
16
  private viewContainerRef;
17
17
  private el;
18
18
  private handleDirective;
19
+ axDrag: _angular_core.InputSignalWithTransform<boolean, string | boolean>;
19
20
  dragData: _angular_core.InputSignal<unknown>;
20
21
  dragDisabled: _angular_core.InputSignal<boolean>;
21
22
  dragTransition: _angular_core.InputSignal<boolean>;
@@ -45,6 +46,8 @@ declare class AXDragDirective implements OnInit, OnDestroy {
45
46
  private dragStartOffset;
46
47
  private clonePointerOffset;
47
48
  private clonedElementViewRef;
49
+ private rafId;
50
+ private pendingPointerEvent;
48
51
  private _parentDropList;
49
52
  private _currentDropList;
50
53
  readonly createCloneElement: _angular_core.Signal<boolean>;
@@ -56,6 +59,7 @@ declare class AXDragDirective implements OnInit, OnDestroy {
56
59
  private boundHandlePointerUp;
57
60
  private boundHandlePointerDown;
58
61
  private boundHandlePointerMove;
62
+ private listenersAttached;
59
63
  ngOnInit(): void;
60
64
  ngOnDestroy(): void;
61
65
  private setElementTransition;
@@ -68,6 +72,7 @@ declare class AXDragDirective implements OnInit, OnDestroy {
68
72
  private preventClicking;
69
73
  private handleDropListInteractions;
70
74
  private canDropInList;
75
+ private isCircularReference;
71
76
  private dropZoneHoverHandler;
72
77
  private dropZoneDropHandler;
73
78
  private getDropZonesFromPoint;
@@ -83,7 +88,7 @@ declare class AXDragDirective implements OnInit, OnDestroy {
83
88
  private addDocumentListeners;
84
89
  private removeDocumentListeners;
85
90
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<AXDragDirective, never>;
86
- static ɵdir: _angular_core.ɵɵDirectiveDeclaration<AXDragDirective, "[axDrag]", never, { "dragData": { "alias": "dragData"; "required": false; "isSignal": true; }; "dragDisabled": { "alias": "dragDisabled"; "required": false; "isSignal": true; }; "dragTransition": { "alias": "dragTransition"; "required": false; "isSignal": true; }; "dragElementClone": { "alias": "dragElementClone"; "required": false; "isSignal": true; }; "dropZoneGroup": { "alias": "dropZoneGroup"; "required": false; "isSignal": true; }; "dragStartDelay": { "alias": "dragStartDelay"; "required": false; "isSignal": true; }; "dragResetOnDblClick": { "alias": "dragResetOnDblClick"; "required": false; "isSignal": true; }; "dragLockAxis": { "alias": "dragLockAxis"; "required": false; "isSignal": true; }; "dragClonedTemplate": { "alias": "dragClonedTemplate"; "required": false; "isSignal": true; }; "dragCursor": { "alias": "dragCursor"; "required": false; "isSignal": true; }; "dragBoundary": { "alias": "dragBoundary"; "required": false; "isSignal": true; }; "dragTransitionDuration": { "alias": "dragTransitionDuration"; "required": false; "isSignal": true; }; }, { "dragPositionChanged": "dragPositionChanged"; }, ["handleDirective"], never, true, never>;
91
+ static ɵdir: _angular_core.ɵɵDirectiveDeclaration<AXDragDirective, "[axDrag]", never, { "axDrag": { "alias": "axDrag"; "required": false; "isSignal": true; }; "dragData": { "alias": "dragData"; "required": false; "isSignal": true; }; "dragDisabled": { "alias": "dragDisabled"; "required": false; "isSignal": true; }; "dragTransition": { "alias": "dragTransition"; "required": false; "isSignal": true; }; "dragElementClone": { "alias": "dragElementClone"; "required": false; "isSignal": true; }; "dropZoneGroup": { "alias": "dropZoneGroup"; "required": false; "isSignal": true; }; "dragStartDelay": { "alias": "dragStartDelay"; "required": false; "isSignal": true; }; "dragResetOnDblClick": { "alias": "dragResetOnDblClick"; "required": false; "isSignal": true; }; "dragLockAxis": { "alias": "dragLockAxis"; "required": false; "isSignal": true; }; "dragClonedTemplate": { "alias": "dragClonedTemplate"; "required": false; "isSignal": true; }; "dragCursor": { "alias": "dragCursor"; "required": false; "isSignal": true; }; "dragBoundary": { "alias": "dragBoundary"; "required": false; "isSignal": true; }; "dragTransitionDuration": { "alias": "dragTransitionDuration"; "required": false; "isSignal": true; }; }, { "dragPositionChanged": "dragPositionChanged"; }, ["handleDirective"], never, true, never>;
87
92
  }
88
93
 
89
94
  declare class AXDragHandleDirective {
@@ -93,45 +98,6 @@ declare class AXDragHandleDirective {
93
98
  static ɵdir: _angular_core.ɵɵDirectiveDeclaration<AXDragHandleDirective, "[axDragHandle]", never, {}, {}, never, never, true, never>;
94
99
  }
95
100
 
96
- interface AXDropZoneDropEvent extends NXNativeEvent<AXDropZoneDirective, MouseEvent> {
97
- dropped: AXDragDirective;
98
- }
99
- type AXDropZoneHoverEvent = AXDropZoneDropEvent & {
100
- state: 'enter' | 'leave';
101
- };
102
- declare class AXDropZoneDirective extends NXComponent implements OnInit {
103
- dropZoneGroup: _angular_core.InputSignal<string>;
104
- isHovered: _angular_core.WritableSignal<boolean>;
105
- readonly element: _angular_core.WritableSignal<HTMLElement>;
106
- onElementDrop: _angular_core.OutputEmitterRef<AXDropZoneDropEvent>;
107
- onElementHover: _angular_core.OutputEmitterRef<AXDropZoneHoverEvent>;
108
- ngOnInit(): void;
109
- static ɵfac: _angular_core.ɵɵFactoryDeclaration<AXDropZoneDirective, never>;
110
- static ɵdir: _angular_core.ɵɵDirectiveDeclaration<AXDropZoneDirective, "[axDropZone]", ["axDropZone"], { "dropZoneGroup": { "alias": "dropZoneGroup"; "required": false; "isSignal": true; }; }, { "onElementDrop": "onElementDrop"; "onElementHover": "onElementHover"; }, never, never, true, never>;
111
- }
112
-
113
- declare class AXDragDropModule {
114
- static ɵfac: _angular_core.ɵɵFactoryDeclaration<AXDragDropModule, never>;
115
- static ɵmod: _angular_core.ɵɵNgModuleDeclaration<AXDragDropModule, never, [typeof AXDragDirective, typeof AXDragHandleDirective, typeof AXDropZoneDirective], [typeof AXDragDirective, typeof AXDragHandleDirective, typeof AXDropZoneDirective]>;
116
- static ɵinj: _angular_core.ɵɵInjectorDeclaration<AXDragDropModule>;
117
- }
118
-
119
- /**
120
- * Moves an item one index in an array to another.
121
- * @param array Array in which to move the item.
122
- * @param fromIndex Starting index of the item.
123
- * @param toIndex Index to which the item should be moved.
124
- */
125
- declare function moveItemInArray<T = any>(array: T[], fromIndex: number, toIndex: number): void;
126
- /**
127
- * Moves an item from one array to another.
128
- * @param currentArray Array from which to transfer the item.
129
- * @param targetArray Array into which to put the item.
130
- * @param currentIndex Index of the item in its current array.
131
- * @param targetIndex Index at which to insert the item.
132
- */
133
- declare function transferArrayItem<T = any>(currentArray: T[], targetArray: T[], currentIndex: number, targetIndex: number): void;
134
-
135
101
  /** Event object emitted when an item is dropped into a drop list. */
136
102
  interface AXDropListDroppedEvent extends NXNativeEvent<AXDropListDirective, MouseEvent> {
137
103
  item: AXDragDirective;
@@ -156,6 +122,8 @@ declare class AXDropListDirective extends NXComponent implements OnInit, AfterCo
156
122
  private readonly _cdr;
157
123
  private readonly _platformId;
158
124
  private readonly _hostEl;
125
+ /** Boolean input matching the directive selector name for conditional application. */
126
+ axDropList: _angular_core.InputSignalWithTransform<boolean, string | boolean>;
159
127
  /** Whether sorting within this list is disabled. */
160
128
  sortingDisabled: _angular_core.InputSignal<boolean>;
161
129
  /** The group this drop list belongs to. Dragging is only allowed between lists of the same group. */
@@ -240,8 +208,47 @@ declare class AXDropListDirective extends NXComponent implements OnInit, AfterCo
240
208
  /** Resets the internal state of the directive to its initial values. */
241
209
  resetSortState(): void;
242
210
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<AXDropListDirective, never>;
243
- static ɵdir: _angular_core.ɵɵDirectiveDeclaration<AXDropListDirective, "[axDropList]", ["axDropList"], { "sortingDisabled": { "alias": "sortingDisabled"; "required": false; "isSignal": true; }; "dropListGroup": { "alias": "dropListGroup"; "required": false; "isSignal": true; }; "dropListOrientation": { "alias": "dropListOrientation"; "required": false; "isSignal": true; }; }, { "dropListDropped": "dropListDropped"; }, ["_draggableItems"], never, true, never>;
211
+ static ɵdir: _angular_core.ɵɵDirectiveDeclaration<AXDropListDirective, "[axDropList]", ["axDropList"], { "axDropList": { "alias": "axDropList"; "required": false; "isSignal": true; }; "sortingDisabled": { "alias": "sortingDisabled"; "required": false; "isSignal": true; }; "dropListGroup": { "alias": "dropListGroup"; "required": false; "isSignal": true; }; "dropListOrientation": { "alias": "dropListOrientation"; "required": false; "isSignal": true; }; }, { "dropListDropped": "dropListDropped"; }, ["_draggableItems"], never, true, never>;
244
212
  }
245
213
 
214
+ interface AXDropZoneDropEvent extends NXNativeEvent<AXDropZoneDirective, MouseEvent> {
215
+ dropped: AXDragDirective;
216
+ }
217
+ type AXDropZoneHoverEvent = AXDropZoneDropEvent & {
218
+ state: 'enter' | 'leave';
219
+ };
220
+ declare class AXDropZoneDirective extends NXComponent implements OnInit {
221
+ dropZoneGroup: _angular_core.InputSignal<string>;
222
+ isHovered: _angular_core.WritableSignal<boolean>;
223
+ readonly element: _angular_core.WritableSignal<HTMLElement>;
224
+ onElementDrop: _angular_core.OutputEmitterRef<AXDropZoneDropEvent>;
225
+ onElementHover: _angular_core.OutputEmitterRef<AXDropZoneHoverEvent>;
226
+ ngOnInit(): void;
227
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<AXDropZoneDirective, never>;
228
+ static ɵdir: _angular_core.ɵɵDirectiveDeclaration<AXDropZoneDirective, "[axDropZone]", ["axDropZone"], { "dropZoneGroup": { "alias": "dropZoneGroup"; "required": false; "isSignal": true; }; }, { "onElementDrop": "onElementDrop"; "onElementHover": "onElementHover"; }, never, never, true, never>;
229
+ }
230
+
231
+ declare class AXDragDropModule {
232
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<AXDragDropModule, never>;
233
+ static ɵmod: _angular_core.ɵɵNgModuleDeclaration<AXDragDropModule, never, [typeof AXDragDirective, typeof AXDragHandleDirective, typeof AXDropListDirective, typeof AXDropZoneDirective], [typeof AXDragDirective, typeof AXDragHandleDirective, typeof AXDropListDirective, typeof AXDropZoneDirective]>;
234
+ static ɵinj: _angular_core.ɵɵInjectorDeclaration<AXDragDropModule>;
235
+ }
236
+
237
+ /**
238
+ * Moves an item one index in an array to another.
239
+ * @param array Array in which to move the item.
240
+ * @param fromIndex Starting index of the item.
241
+ * @param toIndex Index to which the item should be moved.
242
+ */
243
+ declare function moveItemInArray<T = any>(array: T[], fromIndex: number, toIndex: number): void;
244
+ /**
245
+ * Moves an item from one array to another.
246
+ * @param currentArray Array from which to transfer the item.
247
+ * @param targetArray Array into which to put the item.
248
+ * @param currentIndex Index of the item in its current array.
249
+ * @param targetIndex Index at which to insert the item.
250
+ */
251
+ declare function transferArrayItem<T = any>(currentArray: T[], targetArray: T[], currentIndex: number, targetIndex: number): void;
252
+
246
253
  export { AXDragDirective, AXDragDropModule, AXDragHandleDirective, AXDropListDirective, AXDropZoneDirective, moveItemInArray, transferArrayItem };
247
254
  export type { AXDropListDroppedEvent, AXDropZoneDropEvent, AXDropZoneHoverEvent };
@@ -38,6 +38,8 @@ class AXDropListDirective extends NXComponent {
38
38
  this._platformId = inject(PLATFORM_ID);
39
39
  this._hostEl = inject(ElementRef);
40
40
  // --- Public API: Inputs and Outputs ---
41
+ /** Boolean input matching the directive selector name for conditional application. */
42
+ this.axDropList = input(true, ...(ngDevMode ? [{ debugName: "axDropList", transform: (value) => value === '' || value === true }] : [{ transform: (value) => value === '' || value === true }]));
41
43
  /** Whether sorting within this list is disabled. */
42
44
  this.sortingDisabled = input(false, ...(ngDevMode ? [{ debugName: "sortingDisabled" }] : []));
43
45
  /** The group this drop list belongs to. Dragging is only allowed between lists of the same group. */
@@ -83,7 +85,7 @@ class AXDropListDirective extends NXComponent {
83
85
  * @param dragItem The item that is being dragged.
84
86
  */
85
87
  prepareSort(dragItem) {
86
- if (this.sortingDisabled() || this._activeDragItem() || dragItem.dragDisabled())
88
+ if (!this.axDropList() || this.sortingDisabled() || this._activeDragItem() || dragItem.dragDisabled())
87
89
  return;
88
90
  this._activeDragItem.set(dragItem);
89
91
  this.element.classList.add('ax-drop-list-sorting-active');
@@ -100,7 +102,7 @@ class AXDropListDirective extends NXComponent {
100
102
  * @param dragItem The item entering this list.
101
103
  */
102
104
  enter(dragItem) {
103
- if (this.sortingDisabled() || this.isDragActiveForThisList(dragItem))
105
+ if (!this.axDropList() || this.sortingDisabled() || this.isDragActiveForThisList(dragItem))
104
106
  return;
105
107
  this._activeDragItem.set(dragItem);
106
108
  this.element.classList.add('ax-drop-list-sorting-active');
@@ -112,7 +114,10 @@ class AXDropListDirective extends NXComponent {
112
114
  * @param dragItem The item being dragged.
113
115
  */
114
116
  sort(event, dragItem) {
115
- if (!this.isDragActiveForThisList(dragItem) || this.sortingDisabled() || !this._listInitialRect())
117
+ if (!this.axDropList() ||
118
+ !this.isDragActiveForThisList(dragItem) ||
119
+ this.sortingDisabled() ||
120
+ !this._listInitialRect())
116
121
  return;
117
122
  const pointerPosition = this._orientation() === 'vertical' ? event.clientY : event.clientX;
118
123
  const newPlaceholderIndex = this._calculatePlaceholderIndex(pointerPosition);
@@ -128,7 +133,7 @@ class AXDropListDirective extends NXComponent {
128
133
  * @param sourceList The list where the drag originated.
129
134
  */
130
135
  finalizeSort(event, droppedItem, sourceList) {
131
- if (!this.isDragActiveForThisList(droppedItem) || this.sortingDisabled()) {
136
+ if (!this.axDropList() || !this.isDragActiveForThisList(droppedItem) || this.sortingDisabled()) {
132
137
  this.resetSortStateAndStyles(sourceList);
133
138
  return;
134
139
  }
@@ -370,7 +375,7 @@ class AXDropListDirective extends NXComponent {
370
375
  this._listGap.set(0);
371
376
  }
372
377
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.6", ngImport: i0, type: AXDropListDirective, deps: null, target: i0.ɵɵFactoryTarget.Directive }); }
373
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.2.0", version: "20.3.6", type: AXDropListDirective, isStandalone: true, selector: "[axDropList]", inputs: { sortingDisabled: { classPropertyName: "sortingDisabled", publicName: "sortingDisabled", isSignal: true, isRequired: false, transformFunction: null }, dropListGroup: { classPropertyName: "dropListGroup", publicName: "dropListGroup", isSignal: true, isRequired: false, transformFunction: null }, dropListOrientation: { classPropertyName: "dropListOrientation", publicName: "dropListOrientation", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { dropListDropped: "dropListDropped" }, queries: [{ propertyName: "_draggableItems", predicate: AXDragDirective, isSignal: true }], exportAs: ["axDropList"], usesInheritance: true, ngImport: i0 }); }
378
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.2.0", version: "20.3.6", type: AXDropListDirective, isStandalone: true, selector: "[axDropList]", inputs: { axDropList: { classPropertyName: "axDropList", publicName: "axDropList", isSignal: true, isRequired: false, transformFunction: null }, sortingDisabled: { classPropertyName: "sortingDisabled", publicName: "sortingDisabled", isSignal: true, isRequired: false, transformFunction: null }, dropListGroup: { classPropertyName: "dropListGroup", publicName: "dropListGroup", isSignal: true, isRequired: false, transformFunction: null }, dropListOrientation: { classPropertyName: "dropListOrientation", publicName: "dropListOrientation", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { dropListDropped: "dropListDropped" }, queries: [{ propertyName: "_draggableItems", predicate: AXDragDirective, isSignal: true }], exportAs: ["axDropList"], usesInheritance: true, ngImport: i0 }); }
374
379
  }
375
380
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.6", ngImport: i0, type: AXDropListDirective, decorators: [{
376
381
  type: Directive,
@@ -378,7 +383,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.6", ngImpor
378
383
  selector: '[axDropList]',
379
384
  exportAs: 'axDropList',
380
385
  }]
381
- }], propDecorators: { sortingDisabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "sortingDisabled", required: false }] }], dropListGroup: [{ type: i0.Input, args: [{ isSignal: true, alias: "dropListGroup", required: false }] }], dropListOrientation: [{ type: i0.Input, args: [{ isSignal: true, alias: "dropListOrientation", required: false }] }], dropListDropped: [{ type: i0.Output, args: ["dropListDropped"] }], _draggableItems: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => AXDragDirective), { ...{ descendants: false }, isSignal: true }] }] } });
386
+ }], propDecorators: { axDropList: [{ type: i0.Input, args: [{ isSignal: true, alias: "axDropList", required: false }] }], sortingDisabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "sortingDisabled", required: false }] }], dropListGroup: [{ type: i0.Input, args: [{ isSignal: true, alias: "dropListGroup", required: false }] }], dropListOrientation: [{ type: i0.Input, args: [{ isSignal: true, alias: "dropListOrientation", required: false }] }], dropListDropped: [{ type: i0.Output, args: ["dropListDropped"] }], _draggableItems: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => AXDragDirective), { ...{ descendants: false }, isSignal: true }] }] } });
382
387
 
383
388
  class AXDragDirective {
384
389
  constructor() {
@@ -390,6 +395,7 @@ class AXDragDirective {
390
395
  this.viewContainerRef = inject(ViewContainerRef);
391
396
  this.el = inject(ElementRef);
392
397
  this.handleDirective = contentChild(AXDragHandleDirective, ...(ngDevMode ? [{ debugName: "handleDirective" }] : []));
398
+ this.axDrag = input(true, ...(ngDevMode ? [{ debugName: "axDrag", transform: (value) => value === '' || value === true }] : [{ transform: (value) => value === '' || value === true }]));
393
399
  this.dragData = input(...(ngDevMode ? [undefined, { debugName: "dragData" }] : []));
394
400
  this.dragDisabled = input(false, ...(ngDevMode ? [{ debugName: "dragDisabled" }] : []));
395
401
  this.dragTransition = input(true, ...(ngDevMode ? [{ debugName: "dragTransition" }] : []));
@@ -419,6 +425,8 @@ class AXDragDirective {
419
425
  this.dragStartOffset = signal({ x: 0, y: 0 }, ...(ngDevMode ? [{ debugName: "dragStartOffset" }] : []));
420
426
  this.clonePointerOffset = signal({ x: 0, y: 0 }, ...(ngDevMode ? [{ debugName: "clonePointerOffset" }] : []));
421
427
  this.clonedElementViewRef = signal(null, ...(ngDevMode ? [{ debugName: "clonedElementViewRef" }] : []));
428
+ this.rafId = null;
429
+ this.pendingPointerEvent = null;
422
430
  this._parentDropList = inject(AXDropListDirective, { optional: true, skipSelf: true, host: false });
423
431
  this._currentDropList = signal(null, ...(ngDevMode ? [{ debugName: "_currentDropList" }] : []));
424
432
  this.createCloneElement = computed(() => this.dragElementClone() || !!this._parentDropList, ...(ngDevMode ? [{ debugName: "createCloneElement" }] : []));
@@ -449,6 +457,7 @@ class AXDragDirective {
449
457
  this.boundHandlePointerUp = this.handlePointerUp.bind(this);
450
458
  this.boundHandlePointerDown = this.handlePointerDown.bind(this);
451
459
  this.boundHandlePointerMove = this.handlePointerMove.bind(this);
460
+ this.listenersAttached = signal(null, ...(ngDevMode ? [{ debugName: "listenersAttached" }] : []));
452
461
  this.#dragDisabledEffect = effect(() => {
453
462
  if (this.dragCursor() === 'none') {
454
463
  return;
@@ -462,14 +471,30 @@ class AXDragDirective {
462
471
  this.renderer.removeStyle(this.handle(), 'touch-action');
463
472
  }
464
473
  }, ...(ngDevMode ? [{ debugName: "#dragDisabledEffect" }] : []));
474
+ this.#handleChangeEffect = effect(() => {
475
+ if (!isPlatformBrowser(this.platformId))
476
+ return;
477
+ const currentHandle = this.handle();
478
+ const previousHandle = this.listenersAttached();
479
+ // Remove listeners from previous handle if it changed
480
+ if (previousHandle && previousHandle !== currentHandle) {
481
+ previousHandle.removeEventListener('dblclick', this.boundHandleDblClick);
482
+ previousHandle.removeEventListener('pointerdown', this.boundHandlePointerDown);
483
+ }
484
+ // Attach listeners to new handle
485
+ if (currentHandle && currentHandle !== previousHandle) {
486
+ this.zone.runOutsideAngular(() => {
487
+ currentHandle.addEventListener('dblclick', this.boundHandleDblClick);
488
+ currentHandle.addEventListener('pointerdown', this.boundHandlePointerDown, { passive: false });
489
+ });
490
+ this.listenersAttached.set(currentHandle);
491
+ }
492
+ }, ...(ngDevMode ? [{ debugName: "#handleChangeEffect" }] : []));
465
493
  }
466
494
  #dragDisabledEffect;
495
+ #handleChangeEffect;
467
496
  ngOnInit() {
468
497
  if (isPlatformBrowser(this.platformId)) {
469
- this.zone.runOutsideAngular(() => {
470
- this.handle().addEventListener('dblclick', this.boundHandleDblClick);
471
- this.handle().addEventListener('pointerdown', this.boundHandlePointerDown, { passive: false });
472
- });
473
498
  if (this._parentDropList) {
474
499
  this.setElementTransition(this.element());
475
500
  }
@@ -479,8 +504,11 @@ class AXDragDirective {
479
504
  }
480
505
  ngOnDestroy() {
481
506
  if (isPlatformBrowser(this.platformId)) {
482
- this.handle().removeEventListener('dblclick', this.boundHandleDblClick);
483
- this.handle().removeEventListener('pointerdown', this.boundHandlePointerDown);
507
+ const handle = this.listenersAttached();
508
+ if (handle) {
509
+ handle.removeEventListener('dblclick', this.boundHandleDblClick);
510
+ handle.removeEventListener('pointerdown', this.boundHandlePointerDown);
511
+ }
484
512
  this.removeDocumentListeners();
485
513
  if (this.createCloneElement()) {
486
514
  this.removeCloneElement();
@@ -501,7 +529,7 @@ class AXDragDirective {
501
529
  handlePointerDown(e) {
502
530
  if (!isPlatformBrowser(this.platformId))
503
531
  return;
504
- if (this.dragDisabled() || e.button !== 0 || this._parentDropList?.sortingDisabled())
532
+ if (!this.axDrag() || this.dragDisabled() || e.button !== 0 || this._parentDropList?.sortingDisabled())
505
533
  return;
506
534
  this.isDragging.set(true);
507
535
  this.movedAfterDelay.set(false);
@@ -523,8 +551,7 @@ class AXDragDirective {
523
551
  this.setPosition(0, 0);
524
552
  }
525
553
  handlePointerMove(e) {
526
- if (this.movedAfterDelay() ||
527
- !this.isDragging() ||
554
+ if (!this.isDragging() ||
528
555
  this.isDelayStarted() ||
529
556
  !isPlatformBrowser(this.platformId) ||
530
557
  e.pointerId !== this.activePointerId()) {
@@ -533,32 +560,48 @@ class AXDragDirective {
533
560
  e.preventDefault();
534
561
  if (!this.isMoving()) {
535
562
  const delay = this.dragStartDelay() ?? 0;
563
+ // FIX: Delay logic was inverted
536
564
  if (Date.now() - this.dragStartTime() < delay) {
537
- this.movedAfterDelay.set(true);
538
- return;
565
+ return; // Still waiting for delay
539
566
  }
540
567
  this.isMoving.set(true);
541
568
  this.handle().setPointerCapture(e.pointerId);
542
569
  this.startDrag(e);
543
570
  }
544
- if (this.createCloneElement()) {
545
- const newCloneX = e.clientX - this.clonePointerOffset().x;
546
- const newCloneY = e.clientY - this.clonePointerOffset().y;
547
- this.setClonePosition(newCloneX, newCloneY);
548
- }
549
- else {
550
- const newX = e.clientX - this.dragStartOffset().x;
551
- const newY = e.clientY - this.dragStartOffset().y;
552
- this.setPosition(newX, newY);
553
- }
571
+ // Run position updates outside Angular zone for better performance
572
+ this.zone.runOutsideAngular(() => {
573
+ if (this.createCloneElement()) {
574
+ const newCloneX = e.clientX - this.clonePointerOffset().x;
575
+ const newCloneY = e.clientY - this.clonePointerOffset().y;
576
+ this.setClonePosition(newCloneX, newCloneY);
577
+ }
578
+ else {
579
+ const newX = e.clientX - this.dragStartOffset().x;
580
+ const newY = e.clientY - this.dragStartOffset().y;
581
+ this.setPosition(newX, newY);
582
+ }
583
+ });
584
+ // Throttle drop list interactions using requestAnimationFrame
554
585
  if (this._parentDropList) {
555
- this.handleDropListInteractions(e);
586
+ this.pendingPointerEvent = e;
587
+ if (this.rafId === null) {
588
+ this.rafId = requestAnimationFrame(() => {
589
+ if (this.pendingPointerEvent) {
590
+ this.handleDropListInteractions(this.pendingPointerEvent);
591
+ this.pendingPointerEvent = null;
592
+ }
593
+ this.rafId = null;
594
+ });
595
+ }
556
596
  }
557
597
  else {
558
598
  this.dropZoneHoverHandler(e);
559
599
  }
560
600
  }
561
601
  startDrag(e) {
602
+ // Add CDK-style classes
603
+ this.renderer.addClass(this.element(), 'ax-dragging');
604
+ this.renderer.addClass(this.element(), 'ax-drag-placeholder');
562
605
  if (this._parentDropList) {
563
606
  this._currentDropList.set(this._parentDropList);
564
607
  this._parentDropList.prepareSort(this);
@@ -572,7 +615,11 @@ class AXDragDirective {
572
615
  x: e.clientX - elementRect.left,
573
616
  y: e.clientY - elementRect.top,
574
617
  });
575
- this.createCloneElementHandler(this.element());
618
+ const clone = this.createCloneElementHandler(this.element());
619
+ if (clone) {
620
+ this.renderer.addClass(clone, 'ax-drag-preview');
621
+ this.renderer.addClass(clone, 'ax-dragging');
622
+ }
576
623
  }
577
624
  }
578
625
  handlePointerUp(e) {
@@ -585,6 +632,9 @@ class AXDragDirective {
585
632
  const wasMoving = this.isMoving();
586
633
  this.isMoving.set(false);
587
634
  this.isDragging.set(false);
635
+ // Remove CDK-style classes
636
+ this.renderer.removeClass(this.element(), 'ax-dragging');
637
+ this.renderer.removeClass(this.element(), 'ax-drag-placeholder');
588
638
  if (!wasMoving) {
589
639
  this.activePointerId.set(null);
590
640
  this.removeDocumentListeners();
@@ -610,6 +660,12 @@ class AXDragDirective {
610
660
  else {
611
661
  this.dropZoneDropHandler(e);
612
662
  }
663
+ // Cancel any pending RAF callbacks
664
+ if (this.rafId !== null) {
665
+ cancelAnimationFrame(this.rafId);
666
+ this.rafId = null;
667
+ }
668
+ this.pendingPointerEvent = null;
613
669
  this.activePointerId.set(null);
614
670
  this.removeDocumentListeners();
615
671
  this._currentDropList.set(null);
@@ -633,9 +689,21 @@ class AXDragDirective {
633
689
  const listUnderPointer = this.getDropListFromPoint(e.clientX, e.clientY);
634
690
  const previousList = this._currentDropList();
635
691
  let targetList = null;
636
- if (listUnderPointer && this.canDropInList(listUnderPointer)) {
692
+ const canDrop = listUnderPointer && this.canDropInList(listUnderPointer);
693
+ if (canDrop) {
637
694
  targetList = listUnderPointer;
638
695
  }
696
+ // Update cursor based on whether drop is allowed
697
+ if (listUnderPointer) {
698
+ const cloneEl = this.clonedElement();
699
+ const cursor = canDrop ? 'move' : 'not-allowed';
700
+ if (cloneEl) {
701
+ this.renderer.setStyle(cloneEl, 'cursor', cursor);
702
+ }
703
+ else {
704
+ this.renderer.setStyle(this.element(), 'cursor', cursor);
705
+ }
706
+ }
639
707
  if (targetList !== previousList) {
640
708
  if (previousList) {
641
709
  previousList.cancelSortPreview();
@@ -659,7 +727,40 @@ class AXDragDirective {
659
727
  }
660
728
  const dragGroup = this._parentDropList.dropListGroup();
661
729
  const targetGroup = list.dropListGroup();
662
- return !!dragGroup && dragGroup === targetGroup;
730
+ if (!dragGroup || dragGroup !== targetGroup) {
731
+ return false;
732
+ }
733
+ // Check for circular reference (tree-specific validation)
734
+ const draggedNode = this.dragData();
735
+ const targetNodeId = list.element.getAttribute('data-node-id');
736
+ if (draggedNode && this.isCircularReference(targetNodeId, draggedNode)) {
737
+ return false;
738
+ }
739
+ return true;
740
+ }
741
+ isCircularReference(targetNodeId, draggedNode) {
742
+ if (!draggedNode || typeof draggedNode !== 'object') {
743
+ return false;
744
+ }
745
+ const node = draggedNode;
746
+ // Check if dropping into itself
747
+ if (targetNodeId === node.id) {
748
+ return true;
749
+ }
750
+ // Check if targetNodeId is in draggedNode's descendants
751
+ if (!node.children || !Array.isArray(node.children)) {
752
+ return false;
753
+ }
754
+ for (const child of node.children) {
755
+ const childNode = child;
756
+ if (childNode.id === targetNodeId) {
757
+ return true;
758
+ }
759
+ if (this.isCircularReference(targetNodeId, child)) {
760
+ return true;
761
+ }
762
+ }
763
+ return false;
663
764
  }
664
765
  dropZoneHoverHandler(e) {
665
766
  const dropZones = this.getDropZonesFromPoint(e.clientX, e.clientY);
@@ -739,9 +840,14 @@ class AXDragDirective {
739
840
  constrainedY = this.currentAxis().y;
740
841
  if (this.dragLockAxis() === 'y')
741
842
  constrainedX = this.currentAxis().x;
742
- this.currentAxis.set({ x: constrainedX, y: constrainedY });
843
+ // Direct DOM manipulation without triggering change detection
743
844
  this.renderer.setStyle(this.element(), 'translate', `${constrainedX}px ${constrainedY}px`);
744
- this.dragPositionChanged.emit(this.currentAxis());
845
+ // Only update signal and emit if position actually changed significantly (throttle)
846
+ const current = this.currentAxis();
847
+ if (Math.abs(current.x - constrainedX) > 0.5 || Math.abs(current.y - constrainedY) > 0.5) {
848
+ this.currentAxis.set({ x: constrainedX, y: constrainedY });
849
+ this.dragPositionChanged.emit({ x: constrainedX, y: constrainedY });
850
+ }
745
851
  }
746
852
  setClonePosition(x, y) {
747
853
  let constrainedX = x;
@@ -758,9 +864,14 @@ class AXDragDirective {
758
864
  constrainedY = this.currentCloneAxis().y;
759
865
  if (this.dragLockAxis() === 'y')
760
866
  constrainedX = this.currentCloneAxis().x;
761
- this.currentCloneAxis.set({ x: constrainedX, y: constrainedY });
867
+ // Direct DOM manipulation without triggering change detection
762
868
  this.renderer.setStyle(cloneEl, 'translate', `${constrainedX}px ${constrainedY}px`);
763
- this.dragPositionChanged.emit(this.currentCloneAxis());
869
+ // Only update signal and emit if position actually changed significantly (throttle)
870
+ const current = this.currentCloneAxis();
871
+ if (Math.abs(current.x - constrainedX) > 0.5 || Math.abs(current.y - constrainedY) > 0.5) {
872
+ this.currentCloneAxis.set({ x: constrainedX, y: constrainedY });
873
+ this.dragPositionChanged.emit({ x: constrainedX, y: constrainedY });
874
+ }
764
875
  }
765
876
  createCloneElementHandler(originalElement) {
766
877
  if (!isPlatformBrowser(this.platformId)) {
@@ -950,6 +1061,9 @@ class AXDragDirective {
950
1061
  return;
951
1062
  const clone = this.clonedElement();
952
1063
  if (clone?.parentNode) {
1064
+ // Remove classes before removing element
1065
+ this.renderer.removeClass(clone, 'ax-drag-preview');
1066
+ this.renderer.removeClass(clone, 'ax-dragging');
953
1067
  this.renderer.removeChild(clone.parentNode, clone);
954
1068
  }
955
1069
  this.clonedElement.set(null);
@@ -978,14 +1092,14 @@ class AXDragDirective {
978
1092
  });
979
1093
  }
980
1094
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.6", ngImport: i0, type: AXDragDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
981
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.2.0", version: "20.3.6", type: AXDragDirective, isStandalone: true, selector: "[axDrag]", inputs: { dragData: { classPropertyName: "dragData", publicName: "dragData", isSignal: true, isRequired: false, transformFunction: null }, dragDisabled: { classPropertyName: "dragDisabled", publicName: "dragDisabled", isSignal: true, isRequired: false, transformFunction: null }, dragTransition: { classPropertyName: "dragTransition", publicName: "dragTransition", isSignal: true, isRequired: false, transformFunction: null }, dragElementClone: { classPropertyName: "dragElementClone", publicName: "dragElementClone", isSignal: true, isRequired: false, transformFunction: null }, dropZoneGroup: { classPropertyName: "dropZoneGroup", publicName: "dropZoneGroup", isSignal: true, isRequired: false, transformFunction: null }, dragStartDelay: { classPropertyName: "dragStartDelay", publicName: "dragStartDelay", isSignal: true, isRequired: false, transformFunction: null }, dragResetOnDblClick: { classPropertyName: "dragResetOnDblClick", publicName: "dragResetOnDblClick", isSignal: true, isRequired: false, transformFunction: null }, dragLockAxis: { classPropertyName: "dragLockAxis", publicName: "dragLockAxis", isSignal: true, isRequired: false, transformFunction: null }, dragClonedTemplate: { classPropertyName: "dragClonedTemplate", publicName: "dragClonedTemplate", isSignal: true, isRequired: false, transformFunction: null }, dragCursor: { classPropertyName: "dragCursor", publicName: "dragCursor", isSignal: true, isRequired: false, transformFunction: null }, dragBoundary: { classPropertyName: "dragBoundary", publicName: "dragBoundary", isSignal: true, isRequired: false, transformFunction: null }, dragTransitionDuration: { classPropertyName: "dragTransitionDuration", publicName: "dragTransitionDuration", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { dragPositionChanged: "dragPositionChanged" }, queries: [{ propertyName: "handleDirective", first: true, predicate: AXDragHandleDirective, descendants: true, isSignal: true }], ngImport: i0 }); }
1095
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.2.0", version: "20.3.6", type: AXDragDirective, isStandalone: true, selector: "[axDrag]", inputs: { axDrag: { classPropertyName: "axDrag", publicName: "axDrag", isSignal: true, isRequired: false, transformFunction: null }, dragData: { classPropertyName: "dragData", publicName: "dragData", isSignal: true, isRequired: false, transformFunction: null }, dragDisabled: { classPropertyName: "dragDisabled", publicName: "dragDisabled", isSignal: true, isRequired: false, transformFunction: null }, dragTransition: { classPropertyName: "dragTransition", publicName: "dragTransition", isSignal: true, isRequired: false, transformFunction: null }, dragElementClone: { classPropertyName: "dragElementClone", publicName: "dragElementClone", isSignal: true, isRequired: false, transformFunction: null }, dropZoneGroup: { classPropertyName: "dropZoneGroup", publicName: "dropZoneGroup", isSignal: true, isRequired: false, transformFunction: null }, dragStartDelay: { classPropertyName: "dragStartDelay", publicName: "dragStartDelay", isSignal: true, isRequired: false, transformFunction: null }, dragResetOnDblClick: { classPropertyName: "dragResetOnDblClick", publicName: "dragResetOnDblClick", isSignal: true, isRequired: false, transformFunction: null }, dragLockAxis: { classPropertyName: "dragLockAxis", publicName: "dragLockAxis", isSignal: true, isRequired: false, transformFunction: null }, dragClonedTemplate: { classPropertyName: "dragClonedTemplate", publicName: "dragClonedTemplate", isSignal: true, isRequired: false, transformFunction: null }, dragCursor: { classPropertyName: "dragCursor", publicName: "dragCursor", isSignal: true, isRequired: false, transformFunction: null }, dragBoundary: { classPropertyName: "dragBoundary", publicName: "dragBoundary", isSignal: true, isRequired: false, transformFunction: null }, dragTransitionDuration: { classPropertyName: "dragTransitionDuration", publicName: "dragTransitionDuration", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { dragPositionChanged: "dragPositionChanged" }, queries: [{ propertyName: "handleDirective", first: true, predicate: AXDragHandleDirective, descendants: true, isSignal: true }], ngImport: i0 }); }
982
1096
  }
983
1097
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.6", ngImport: i0, type: AXDragDirective, decorators: [{
984
1098
  type: Directive,
985
1099
  args: [{
986
1100
  selector: '[axDrag]',
987
1101
  }]
988
- }], propDecorators: { handleDirective: [{ type: i0.ContentChild, args: [i0.forwardRef(() => AXDragHandleDirective), { isSignal: true }] }], dragData: [{ type: i0.Input, args: [{ isSignal: true, alias: "dragData", required: false }] }], dragDisabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "dragDisabled", required: false }] }], dragTransition: [{ type: i0.Input, args: [{ isSignal: true, alias: "dragTransition", required: false }] }], dragElementClone: [{ type: i0.Input, args: [{ isSignal: true, alias: "dragElementClone", required: false }] }], dropZoneGroup: [{ type: i0.Input, args: [{ isSignal: true, alias: "dropZoneGroup", required: false }] }], dragStartDelay: [{ type: i0.Input, args: [{ isSignal: true, alias: "dragStartDelay", required: false }] }], dragResetOnDblClick: [{ type: i0.Input, args: [{ isSignal: true, alias: "dragResetOnDblClick", required: false }] }], dragLockAxis: [{ type: i0.Input, args: [{ isSignal: true, alias: "dragLockAxis", required: false }] }], dragClonedTemplate: [{ type: i0.Input, args: [{ isSignal: true, alias: "dragClonedTemplate", required: false }] }], dragCursor: [{ type: i0.Input, args: [{ isSignal: true, alias: "dragCursor", required: false }] }], dragBoundary: [{ type: i0.Input, args: [{ isSignal: true, alias: "dragBoundary", required: false }] }], dragTransitionDuration: [{ type: i0.Input, args: [{ isSignal: true, alias: "dragTransitionDuration", required: false }] }], dragPositionChanged: [{ type: i0.Output, args: ["dragPositionChanged"] }] } });
1102
+ }], propDecorators: { handleDirective: [{ type: i0.ContentChild, args: [i0.forwardRef(() => AXDragHandleDirective), { isSignal: true }] }], axDrag: [{ type: i0.Input, args: [{ isSignal: true, alias: "axDrag", required: false }] }], dragData: [{ type: i0.Input, args: [{ isSignal: true, alias: "dragData", required: false }] }], dragDisabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "dragDisabled", required: false }] }], dragTransition: [{ type: i0.Input, args: [{ isSignal: true, alias: "dragTransition", required: false }] }], dragElementClone: [{ type: i0.Input, args: [{ isSignal: true, alias: "dragElementClone", required: false }] }], dropZoneGroup: [{ type: i0.Input, args: [{ isSignal: true, alias: "dropZoneGroup", required: false }] }], dragStartDelay: [{ type: i0.Input, args: [{ isSignal: true, alias: "dragStartDelay", required: false }] }], dragResetOnDblClick: [{ type: i0.Input, args: [{ isSignal: true, alias: "dragResetOnDblClick", required: false }] }], dragLockAxis: [{ type: i0.Input, args: [{ isSignal: true, alias: "dragLockAxis", required: false }] }], dragClonedTemplate: [{ type: i0.Input, args: [{ isSignal: true, alias: "dragClonedTemplate", required: false }] }], dragCursor: [{ type: i0.Input, args: [{ isSignal: true, alias: "dragCursor", required: false }] }], dragBoundary: [{ type: i0.Input, args: [{ isSignal: true, alias: "dragBoundary", required: false }] }], dragTransitionDuration: [{ type: i0.Input, args: [{ isSignal: true, alias: "dragTransitionDuration", required: false }] }], dragPositionChanged: [{ type: i0.Output, args: ["dragPositionChanged"] }] } });
989
1103
 
990
1104
  class AXDropZoneDirective extends NXComponent {
991
1105
  constructor() {
@@ -1010,10 +1124,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.6", ngImpor
1010
1124
  }]
1011
1125
  }], propDecorators: { dropZoneGroup: [{ type: i0.Input, args: [{ isSignal: true, alias: "dropZoneGroup", required: false }] }], onElementDrop: [{ type: i0.Output, args: ["onElementDrop"] }], onElementHover: [{ type: i0.Output, args: ["onElementHover"] }] } });
1012
1126
 
1013
- const COMPONENT = [AXDragDirective, AXDragHandleDirective, AXDropZoneDirective];
1127
+ const COMPONENT = [AXDragDirective, AXDragHandleDirective, AXDropListDirective, AXDropZoneDirective];
1014
1128
  class AXDragDropModule {
1015
1129
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.6", ngImport: i0, type: AXDragDropModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
1016
- static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.3.6", ngImport: i0, type: AXDragDropModule, imports: [AXDragDirective, AXDragHandleDirective, AXDropZoneDirective], exports: [AXDragDirective, AXDragHandleDirective, AXDropZoneDirective] }); }
1130
+ static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.3.6", ngImport: i0, type: AXDragDropModule, imports: [AXDragDirective, AXDragHandleDirective, AXDropListDirective, AXDropZoneDirective], exports: [AXDragDirective, AXDragHandleDirective, AXDropListDirective, AXDropZoneDirective] }); }
1017
1131
  static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.3.6", ngImport: i0, type: AXDragDropModule }); }
1018
1132
  }
1019
1133
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.6", ngImport: i0, type: AXDragDropModule, decorators: [{