@ngstarter-ui/components 21.0.38 → 21.0.40

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.
@@ -1,5 +1,5 @@
1
1
  import * as i0 from '@angular/core';
2
- import { inject, ViewContainerRef, Directive, input, booleanAttribute, output, signal, effect, ViewChild, ChangeDetectionStrategy, Component, createComponent, ElementRef, Renderer2, ApplicationRef, EnvironmentInjector, PLATFORM_ID, numberAttribute, HostAttributeToken } from '@angular/core';
2
+ import { inject, ViewContainerRef, Directive, TemplateRef, input, booleanAttribute, output, signal, effect, ViewChild, ContentChild, ChangeDetectionStrategy, Component, createComponent, ElementRef, Renderer2, ApplicationRef, EnvironmentInjector, PLATFORM_ID, numberAttribute, HostAttributeToken } from '@angular/core';
3
3
  import { CDK_TREE_NODE_OUTLET_NODE, CdkTreeNodeOutlet, CdkTree, CdkTreeNode, CdkNestedTreeNode, CdkTreeNodePadding, CdkTreeNodeToggle, CdkTreeNodeDef } from '@angular/cdk/tree';
4
4
  import { isPlatformBrowser } from '@angular/common';
5
5
  import { Checkbox } from '@ngstarter-ui/components/checkbox';
@@ -43,6 +43,21 @@ const NGS_TREE_DEFAULT_FILTER_PREDICATE = (node, filterValue) => {
43
43
  : [node];
44
44
  return candidates.some(value => value != null && String(value).toLowerCase().includes(query));
45
45
  };
46
+ class TreeDragPlaceholder {
47
+ templateRef = inject(TemplateRef);
48
+ static ngTemplateContextGuard(_directive, _context) {
49
+ return true;
50
+ }
51
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: TreeDragPlaceholder, deps: [], target: i0.ɵɵFactoryTarget.Directive });
52
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.4", type: TreeDragPlaceholder, isStandalone: true, selector: "ng-template[ngsTreeDragPlaceholder]", ngImport: i0 });
53
+ }
54
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: TreeDragPlaceholder, decorators: [{
55
+ type: Directive,
56
+ args: [{
57
+ selector: 'ng-template[ngsTreeDragPlaceholder]',
58
+ standalone: true
59
+ }]
60
+ }] });
46
61
  class Tree extends CdkTree {
47
62
  get dataSource() {
48
63
  return this._sourceDataSource ?? [];
@@ -56,6 +71,10 @@ class Tree extends CdkTree {
56
71
  checkable = input(false, { ...(ngDevMode ? { debugName: "checkable" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
57
72
  selectable = input(false, { ...(ngDevMode ? { debugName: "selectable" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
58
73
  draggable = input(false, { ...(ngDevMode ? { debugName: "draggable" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
74
+ draggablePredicate = input(() => true, ...(ngDevMode ? [{ debugName: "draggablePredicate" }] : /* istanbul ignore next */ []));
75
+ dropPredicate = input(() => true, ...(ngDevMode ? [{ debugName: "dropPredicate" }] : /* istanbul ignore next */ []));
76
+ reorderOnDrop = input(true, { ...(ngDevMode ? { debugName: "reorderOnDrop" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
77
+ dragPreview = input('node', ...(ngDevMode ? [{ debugName: "dragPreview" }] : /* istanbul ignore next */ []));
59
78
  childrenKey = input('children', ...(ngDevMode ? [{ debugName: "childrenKey" }] : /* istanbul ignore next */ []));
60
79
  filterValue = input('', { ...(ngDevMode ? { debugName: "filterValue" } : /* istanbul ignore next */ {}), transform: (value) => value == null ? '' : String(value) });
61
80
  filterPredicate = input(NGS_TREE_DEFAULT_FILTER_PREDICATE, ...(ngDevMode ? [{ debugName: "filterPredicate" }] : /* istanbul ignore next */ []));
@@ -67,6 +86,7 @@ class Tree extends CdkTree {
67
86
  _selectedKey = signal(undefined, ...(ngDevMode ? [{ debugName: "_selectedKey" }] : /* istanbul ignore next */ []));
68
87
  _dropTargetKey = signal(undefined, ...(ngDevMode ? [{ debugName: "_dropTargetKey" }] : /* istanbul ignore next */ []));
69
88
  _dropTargetPosition = signal(undefined, ...(ngDevMode ? [{ debugName: "_dropTargetPosition" }] : /* istanbul ignore next */ []));
89
+ _draggedNodeKey = signal(undefined, ...(ngDevMode ? [{ debugName: "_draggedNodeKey" }] : /* istanbul ignore next */ []));
70
90
  _checkedKeys = new Set();
71
91
  _nodeValueByDataKey = new Map();
72
92
  _disabledDataKeys = new Set();
@@ -74,6 +94,7 @@ class Tree extends CdkTree {
74
94
  _draggedNode;
75
95
  _sourceDataSource;
76
96
  _filteredNodeOriginals = new WeakMap();
97
+ _dragPlaceholder;
77
98
  _nodeOutlet = undefined;
78
99
  constructor() {
79
100
  super();
@@ -138,7 +159,10 @@ class Tree extends CdkTree {
138
159
  return !this._isNodeDisabled(node) && Object.is(this._selectedKey(), this._getTreeNodeValue(node));
139
160
  }
140
161
  _canDragNode(node) {
141
- return node !== undefined && this.draggable() && !this._isNodeDisabled(node);
162
+ return node !== undefined
163
+ && this.draggable()
164
+ && !this._isNodeDisabled(node)
165
+ && this.draggablePredicate()(node);
142
166
  }
143
167
  _isNodeDropTarget(node) {
144
168
  return node !== undefined && Object.is(this._dropTargetKey(), this._getTreeNodeDataKey(node));
@@ -146,12 +170,16 @@ class Tree extends CdkTree {
146
170
  _isNodeDropTargetPosition(node, position) {
147
171
  return this._isNodeDropTarget(node) && this._dropTargetPosition() === position;
148
172
  }
173
+ _isNodeDraggingSource(node) {
174
+ return node !== undefined && Object.is(this._draggedNodeKey(), this._getTreeNodeDataKey(node));
175
+ }
149
176
  _startNodeDrag(node, event) {
150
177
  if (!this._canDragNode(node)) {
151
178
  event.preventDefault();
152
179
  return;
153
180
  }
154
181
  this._draggedNode = node;
182
+ this._draggedNodeKey.set(this._getTreeNodeDataKey(node));
155
183
  if (event.dataTransfer) {
156
184
  event.dataTransfer.effectAllowed = 'move';
157
185
  event.dataTransfer.setData('text/plain', String(this._getTreeNodeValue(node) ?? ''));
@@ -185,7 +213,7 @@ class Tree extends CdkTree {
185
213
  event.preventDefault();
186
214
  event.stopPropagation();
187
215
  const source = this._draggedNode;
188
- const moved = this._moveNode(source, node, position);
216
+ const moved = this.reorderOnDrop() ? this._moveNode(source, node, position) : true;
189
217
  this._clearNodeDrag();
190
218
  if (moved) {
191
219
  this.nodeDrop.emit({
@@ -201,6 +229,45 @@ class Tree extends CdkTree {
201
229
  _endNodeDrag() {
202
230
  this._clearNodeDrag();
203
231
  }
232
+ _getDragPreview() {
233
+ return this.dragPreview();
234
+ }
235
+ _hasDragPlaceholder() {
236
+ return !!this._dragPlaceholder;
237
+ }
238
+ _setDragPlaceholderImage(node, event, host) {
239
+ const template = this._dragPlaceholder?.templateRef;
240
+ const dataTransfer = event.dataTransfer;
241
+ const body = host.ownerDocument.body;
242
+ if (!template || !dataTransfer || !body) {
243
+ return false;
244
+ }
245
+ const viewRef = template.createEmbeddedView({
246
+ $implicit: node,
247
+ source: node,
248
+ });
249
+ viewRef.detectChanges();
250
+ const dragImage = host.ownerDocument.createElement('div');
251
+ dragImage.classList.add('ngs-tree-drag-placeholder-image');
252
+ dragImage.style.position = 'fixed';
253
+ dragImage.style.insetBlockStart = '0';
254
+ dragImage.style.insetInlineStart = '0';
255
+ dragImage.style.zIndex = '-1';
256
+ dragImage.style.pointerEvents = 'none';
257
+ dragImage.style.transform = 'translate(-200vw, -200vh)';
258
+ for (const rootNode of viewRef.rootNodes) {
259
+ if (rootNode instanceof Node) {
260
+ dragImage.appendChild(rootNode);
261
+ }
262
+ }
263
+ body.appendChild(dragImage);
264
+ dataTransfer.setDragImage(dragImage, 12, 12);
265
+ window.setTimeout(() => {
266
+ viewRef.destroy();
267
+ dragImage.remove();
268
+ });
269
+ return true;
270
+ }
204
271
  _registerNodeValue(node, value) {
205
272
  const key = this._getTreeNodeDataKey(node);
206
273
  this._nodeValueByDataKey.set(key, value);
@@ -255,7 +322,8 @@ class Tree extends CdkTree {
255
322
  && this.draggable()
256
323
  && !this._isNodeDisabled(target)
257
324
  && !this._isSameNode(source, target)
258
- && !this._isNodeDescendantOf(target, source);
325
+ && !this._isNodeDescendantOf(target, source)
326
+ && this.dropPredicate()(source, target, position);
259
327
  }
260
328
  _moveNode(source, target, position) {
261
329
  const rootNodes = this._getRootNodes();
@@ -455,6 +523,7 @@ class Tree extends CdkTree {
455
523
  }
456
524
  _clearNodeDrag() {
457
525
  this._draggedNode = undefined;
526
+ this._draggedNodeKey.set(undefined);
458
527
  this._dropTargetKey.set(undefined);
459
528
  this._dropTargetPosition.set(undefined);
460
529
  }
@@ -573,7 +642,7 @@ class Tree extends CdkTree {
573
642
  return node;
574
643
  }
575
644
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: Tree, deps: [], target: i0.ɵɵFactoryTarget.Component });
576
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.4", type: Tree, isStandalone: true, selector: "ngs-tree", inputs: { checkable: { classPropertyName: "checkable", publicName: "checkable", isSignal: true, isRequired: false, transformFunction: null }, selectable: { classPropertyName: "selectable", publicName: "selectable", isSignal: true, isRequired: false, transformFunction: null }, draggable: { classPropertyName: "draggable", publicName: "draggable", isSignal: true, isRequired: false, transformFunction: null }, childrenKey: { classPropertyName: "childrenKey", publicName: "childrenKey", isSignal: true, isRequired: false, transformFunction: null }, filterValue: { classPropertyName: "filterValue", publicName: "filterValue", isSignal: true, isRequired: false, transformFunction: null }, filterPredicate: { classPropertyName: "filterPredicate", publicName: "filterPredicate", isSignal: true, isRequired: false, transformFunction: null }, filterMode: { classPropertyName: "filterMode", publicName: "filterMode", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { checkedChange: "checkedChange", selectedChange: "selectedChange", nodeDrop: "nodeDrop" }, host: { classAttribute: "ngs-tree" }, providers: [{ provide: CdkTree, useExisting: Tree }], viewQueries: [{ propertyName: "_nodeOutlet", first: true, predicate: TreeNodeOutlet, descendants: true, static: true }], exportAs: ["ngsTree"], usesInheritance: true, ngImport: i0, template: `<ng-container ngsTreeNodeOutlet />`, isInline: true, styles: [":host{--ngs-tree-padding: calc(var(--spacing, .25rem) * 3) 0;--ngs-tree-node-padding: var(--ngs-nav-item-padding);--ngs-tree-node-min-height: var(--ngs-nav-item-height);--ngs-tree-node-hover-bg: var(--ngs-nav-item-hover-bg);--ngs-tree-node-active-bg: var(--ngs-nav-item-active-bg);--ngs-tree-node-active-color: var(--ngs-nav-item-active-color);--ngs-tree-node-disabled-opacity: .38;--ngs-tree-node-title-font-size: 1rem;--ngs-tree-node-font-size: var(--ngs-nav-item-font-size);--ngs-tree-node-gap: var(--ngs-nav-item-gap);--ngs-tree-node-radius: var(--ngs-nav-item-radius);--ngs-tree-node-color: var(--ngs-nav-item-color);--ngs-tree-node-hover-color: var(--ngs-nav-item-hover-color);--ngs-tree-gap: calc(var(--spacing, .25rem) * 1);--ngs-tree-node-line-color: var(--ngs-color-neutral);display:flex;flex-direction:column;gap:var(--ngs-tree-gap);padding:var(--ngs-tree-padding);background:var(--ngs-tree-container-background-color, transparent)}\n/*! tailwindcss v4.2.2 | MIT License | https://tailwindcss.com */\n"], dependencies: [{ kind: "directive", type: TreeNodeOutlet, selector: "[ngsTreeNodeOutlet]" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
645
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.4", type: Tree, isStandalone: true, selector: "ngs-tree", inputs: { checkable: { classPropertyName: "checkable", publicName: "checkable", isSignal: true, isRequired: false, transformFunction: null }, selectable: { classPropertyName: "selectable", publicName: "selectable", isSignal: true, isRequired: false, transformFunction: null }, draggable: { classPropertyName: "draggable", publicName: "draggable", isSignal: true, isRequired: false, transformFunction: null }, draggablePredicate: { classPropertyName: "draggablePredicate", publicName: "draggablePredicate", isSignal: true, isRequired: false, transformFunction: null }, dropPredicate: { classPropertyName: "dropPredicate", publicName: "dropPredicate", isSignal: true, isRequired: false, transformFunction: null }, reorderOnDrop: { classPropertyName: "reorderOnDrop", publicName: "reorderOnDrop", isSignal: true, isRequired: false, transformFunction: null }, dragPreview: { classPropertyName: "dragPreview", publicName: "dragPreview", isSignal: true, isRequired: false, transformFunction: null }, childrenKey: { classPropertyName: "childrenKey", publicName: "childrenKey", isSignal: true, isRequired: false, transformFunction: null }, filterValue: { classPropertyName: "filterValue", publicName: "filterValue", isSignal: true, isRequired: false, transformFunction: null }, filterPredicate: { classPropertyName: "filterPredicate", publicName: "filterPredicate", isSignal: true, isRequired: false, transformFunction: null }, filterMode: { classPropertyName: "filterMode", publicName: "filterMode", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { checkedChange: "checkedChange", selectedChange: "selectedChange", nodeDrop: "nodeDrop" }, host: { classAttribute: "ngs-tree" }, providers: [{ provide: CdkTree, useExisting: Tree }], queries: [{ propertyName: "_dragPlaceholder", first: true, predicate: TreeDragPlaceholder, descendants: true }], viewQueries: [{ propertyName: "_nodeOutlet", first: true, predicate: TreeNodeOutlet, descendants: true, static: true }], exportAs: ["ngsTree"], usesInheritance: true, ngImport: i0, template: `<ng-container ngsTreeNodeOutlet />`, isInline: true, styles: [":host{--ngs-tree-padding: calc(var(--spacing, .25rem) * 3) 0;--ngs-tree-node-padding: var(--ngs-nav-item-padding);--ngs-tree-node-min-height: var(--ngs-nav-item-height);--ngs-tree-node-hover-bg: var(--ngs-nav-item-hover-bg);--ngs-tree-node-active-bg: var(--ngs-nav-item-active-bg);--ngs-tree-node-active-color: var(--ngs-nav-item-active-color);--ngs-tree-node-disabled-opacity: .38;--ngs-tree-node-title-font-size: 1rem;--ngs-tree-node-font-size: var(--ngs-nav-item-font-size);--ngs-tree-node-gap: var(--ngs-nav-item-gap);--ngs-tree-node-radius: var(--ngs-nav-item-radius);--ngs-tree-node-color: var(--ngs-nav-item-color);--ngs-tree-node-hover-color: var(--ngs-nav-item-hover-color);--ngs-tree-gap: calc(var(--spacing, .25rem) * 1);--ngs-tree-node-line-color: var(--ngs-color-neutral);display:flex;flex-direction:column;gap:var(--ngs-tree-gap);padding:var(--ngs-tree-padding);background:var(--ngs-tree-container-background-color, transparent)}\n/*! tailwindcss v4.2.2 | MIT License | https://tailwindcss.com */\n"], dependencies: [{ kind: "directive", type: TreeNodeOutlet, selector: "[ngsTreeNodeOutlet]" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
577
646
  }
578
647
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: Tree, decorators: [{
579
648
  type: Component,
@@ -582,7 +651,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImpor
582
651
  ], template: `<ng-container ngsTreeNodeOutlet />`, changeDetection: ChangeDetectionStrategy.OnPush, providers: [{ provide: CdkTree, useExisting: Tree }], host: {
583
652
  'class': 'ngs-tree',
584
653
  }, styles: [":host{--ngs-tree-padding: calc(var(--spacing, .25rem) * 3) 0;--ngs-tree-node-padding: var(--ngs-nav-item-padding);--ngs-tree-node-min-height: var(--ngs-nav-item-height);--ngs-tree-node-hover-bg: var(--ngs-nav-item-hover-bg);--ngs-tree-node-active-bg: var(--ngs-nav-item-active-bg);--ngs-tree-node-active-color: var(--ngs-nav-item-active-color);--ngs-tree-node-disabled-opacity: .38;--ngs-tree-node-title-font-size: 1rem;--ngs-tree-node-font-size: var(--ngs-nav-item-font-size);--ngs-tree-node-gap: var(--ngs-nav-item-gap);--ngs-tree-node-radius: var(--ngs-nav-item-radius);--ngs-tree-node-color: var(--ngs-nav-item-color);--ngs-tree-node-hover-color: var(--ngs-nav-item-hover-color);--ngs-tree-gap: calc(var(--spacing, .25rem) * 1);--ngs-tree-node-line-color: var(--ngs-color-neutral);display:flex;flex-direction:column;gap:var(--ngs-tree-gap);padding:var(--ngs-tree-padding);background:var(--ngs-tree-container-background-color, transparent)}\n/*! tailwindcss v4.2.2 | MIT License | https://tailwindcss.com */\n"] }]
585
- }], ctorParameters: () => [], propDecorators: { checkable: [{ type: i0.Input, args: [{ isSignal: true, alias: "checkable", required: false }] }], selectable: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectable", required: false }] }], draggable: [{ type: i0.Input, args: [{ isSignal: true, alias: "draggable", required: false }] }], childrenKey: [{ type: i0.Input, args: [{ isSignal: true, alias: "childrenKey", required: false }] }], filterValue: [{ type: i0.Input, args: [{ isSignal: true, alias: "filterValue", required: false }] }], filterPredicate: [{ type: i0.Input, args: [{ isSignal: true, alias: "filterPredicate", required: false }] }], filterMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "filterMode", required: false }] }], checkedChange: [{ type: i0.Output, args: ["checkedChange"] }], selectedChange: [{ type: i0.Output, args: ["selectedChange"] }], nodeDrop: [{ type: i0.Output, args: ["nodeDrop"] }], _nodeOutlet: [{
654
+ }], ctorParameters: () => [], propDecorators: { checkable: [{ type: i0.Input, args: [{ isSignal: true, alias: "checkable", required: false }] }], selectable: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectable", required: false }] }], draggable: [{ type: i0.Input, args: [{ isSignal: true, alias: "draggable", required: false }] }], draggablePredicate: [{ type: i0.Input, args: [{ isSignal: true, alias: "draggablePredicate", required: false }] }], dropPredicate: [{ type: i0.Input, args: [{ isSignal: true, alias: "dropPredicate", required: false }] }], reorderOnDrop: [{ type: i0.Input, args: [{ isSignal: true, alias: "reorderOnDrop", required: false }] }], dragPreview: [{ type: i0.Input, args: [{ isSignal: true, alias: "dragPreview", required: false }] }], childrenKey: [{ type: i0.Input, args: [{ isSignal: true, alias: "childrenKey", required: false }] }], filterValue: [{ type: i0.Input, args: [{ isSignal: true, alias: "filterValue", required: false }] }], filterPredicate: [{ type: i0.Input, args: [{ isSignal: true, alias: "filterPredicate", required: false }] }], filterMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "filterMode", required: false }] }], checkedChange: [{ type: i0.Output, args: ["checkedChange"] }], selectedChange: [{ type: i0.Output, args: ["selectedChange"] }], nodeDrop: [{ type: i0.Output, args: ["nodeDrop"] }], _dragPlaceholder: [{
655
+ type: ContentChild,
656
+ args: [TreeDragPlaceholder]
657
+ }], _nodeOutlet: [{
586
658
  type: ViewChild,
587
659
  args: [TreeNodeOutlet, { static: true }]
588
660
  }] } });
@@ -599,6 +671,32 @@ function isTreeNodeControlClick(event, host) {
599
671
  const control = target.closest('.ngs-tree-node-checkbox, [ngsTreeNodeToggle], [ngstreenodetoggle]');
600
672
  return !!control && control !== host;
601
673
  }
674
+ function setTreeNodeDragImage(event, host) {
675
+ const dataTransfer = event.dataTransfer;
676
+ const body = host.ownerDocument.body;
677
+ if (!dataTransfer || !body) {
678
+ return;
679
+ }
680
+ const rect = host.getBoundingClientRect();
681
+ const clone = host.cloneNode(true);
682
+ if (!(clone instanceof HTMLElement)) {
683
+ return;
684
+ }
685
+ clone.classList.add('ngs-tree-node-drag-image');
686
+ clone.style.width = `${rect.width}px`;
687
+ body.appendChild(clone);
688
+ dataTransfer.setDragImage(clone, Math.max(0, Math.min(event.clientX - rect.left, rect.width)), Math.max(0, Math.min(event.clientY - rect.top, rect.height)));
689
+ window.setTimeout(() => clone.remove());
690
+ }
691
+ function setEmptyTreeNodeDragImage(event) {
692
+ const dataTransfer = event.dataTransfer;
693
+ if (!dataTransfer) {
694
+ return;
695
+ }
696
+ const image = new Image();
697
+ image.src = 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==';
698
+ dataTransfer.setDragImage(image, 0, 0);
699
+ }
602
700
  class TreeNodeCheckbox {
603
701
  _node;
604
702
  _tree;
@@ -778,6 +876,9 @@ class TreeNode extends CdkTreeNode {
778
876
  _isDropTargetPosition(position) {
779
877
  return this._tree._isNodeDropTargetPosition(this.data, position);
780
878
  }
879
+ _isDraggingSource() {
880
+ return this._tree._isNodeDraggingSource(this.data);
881
+ }
781
882
  _getDraggableAttribute() {
782
883
  return this._isDraggable() ? true : null;
783
884
  }
@@ -786,6 +887,9 @@ class TreeNode extends CdkTreeNode {
786
887
  }
787
888
  _handleDragStart(event) {
788
889
  this._tree._startNodeDrag(this.data, event);
890
+ if (!event.defaultPrevented) {
891
+ this._setDragImage(event);
892
+ }
789
893
  }
790
894
  _handleDragOver(event) {
791
895
  this._tree._dragNodeOver(this.data, event);
@@ -799,6 +903,16 @@ class TreeNode extends CdkTreeNode {
799
903
  _handleDragEnd() {
800
904
  this._tree._endNodeDrag();
801
905
  }
906
+ _setDragImage(event) {
907
+ if (this._tree._getDragPreview() === 'none') {
908
+ setEmptyTreeNodeDragImage(event);
909
+ return;
910
+ }
911
+ if (this._tree._setDragPlaceholderImage(this.data, event, this._hostElementRef.nativeElement)) {
912
+ return;
913
+ }
914
+ setTreeNodeDragImage(event, this._hostElementRef.nativeElement);
915
+ }
802
916
  _selectNodeFromEvent(event) {
803
917
  if (!this._isSelectable() || this._isTreeControlClick(event)) {
804
918
  return;
@@ -854,16 +968,17 @@ class TreeNode extends CdkTreeNode {
854
968
  super.ngOnDestroy();
855
969
  }
856
970
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: TreeNode, deps: [], target: i0.ɵɵFactoryTarget.Component });
857
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.4", type: TreeNode, isStandalone: true, selector: "ngs-tree-node", inputs: { tabIndexInputBinding: { classPropertyName: "tabIndexInputBinding", publicName: "tabIndex", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { activation: "activation", expandedChange: "expandedChange" }, host: { listeners: { "click": "_handleNodeClick($event)", "dragstart": "_handleDragStart($event)", "dragover": "_handleDragOver($event)", "dragleave": "_handleDragLeave($event)", "drop": "_handleDrop($event)", "dragend": "_handleDragEnd()" }, properties: { "class.ngs-tree-node-selectable": "_isSelectable()", "class.ngs-tree-node-selected": "_isSelected()", "class.ngs-tree-node-disabled": "disabled()", "class.ngs-tree-node-draggable": "_isDraggable()", "class.ngs-tree-node-drop-target": "_isDropTarget()", "class.ngs-tree-node-drop-before": "_isDropTargetPosition(\"before\")", "class.ngs-tree-node-drop-inside": "_isDropTargetPosition(\"inside\")", "class.ngs-tree-node-drop-after": "_isDropTargetPosition(\"after\")", "attr.draggable": "_getDraggableAttribute()", "attr.aria-expanded": "_getAriaExpanded()", "attr.aria-level": "level + 1", "attr.aria-posinset": "_getPositionInSet()", "attr.aria-setsize": "_getSetSize()", "attr.aria-selected": "_getAriaSelected()", "attr.aria-disabled": "disabled()", "attr.aria-grabbed": "_getAriaGrabbed()", "tabindex": "_getTabindexAttribute()" }, classAttribute: "ngs-tree-node" }, providers: [{ provide: CdkTreeNode, useExisting: TreeNode }], exportAs: ["ngsTreeNode"], usesInheritance: true, ngImport: i0, template: '<ng-content />', isInline: true, styles: [":host{color:var(--ngs-tree-node-color);font-size:var(--ngs-tree-node-font-size);position:relative}:host.ngs-tree-node{display:flex;align-items:center;flex:1;gap:var(--ngs-tree-node-gap);padding:var(--ngs-tree-node-padding);word-wrap:break-word;min-height:var(--ngs-tree-node-min-height);box-sizing:border-box}:host.ngs-nested-tree-node{border-bottom-width:0}:host.ngs-tree-node-selectable{border-radius:var(--ngs-tree-node-radius);cursor:pointer}:host.ngs-tree-node-disabled{opacity:var(--ngs-tree-node-disabled-opacity);cursor:default}:host.ngs-tree-node-draggable{cursor:grab}:host.ngs-tree-node-draggable:active{cursor:grabbing}:host.ngs-tree-node-drop-inside{color:var(--ngs-tree-node-drop-target-color, var(--ngs-tree-node-active-color));background:var(--ngs-tree-node-drop-target-bg, var(--ngs-tree-node-active-bg));outline:var(--ngs-tree-node-drop-target-outline, 1px solid var(--ngs-color-primary));outline-offset:var(--ngs-tree-node-drop-target-outline-offset, -1px)}:host.ngs-tree-node-drop-before:before,:host.ngs-tree-node-drop-after:after{content:\"\";position:absolute;z-index:1;inset-inline:0;height:var(--ngs-tree-node-drop-line-size, 2px);background:var(--ngs-tree-node-drop-line-color, var(--ngs-color-primary));border-radius:var(--ngs-tree-node-drop-line-radius, 999px);pointer-events:none}:host.ngs-tree-node-drop-before:before{top:0}:host.ngs-tree-node-drop-after:after{bottom:0}:host.ngs-tree-node-selectable:not(.ngs-tree-node-selected,.ngs-tree-node-disabled):hover{color:var(--ngs-tree-node-hover-color);background:var(--ngs-tree-node-hover-bg)}:host.ngs-tree-node-selected:not(.ngs-tree-node-disabled){color:var(--ngs-tree-node-active-color);background:var(--ngs-tree-node-active-bg)}:host.ngs-tree-node-selectable>button:disabled{pointer-events:none}:host .ngs-tree-node-checkbox{display:inline-flex;align-items:center;justify-content:center;flex:none;margin-inline-end:var(--ngs-tree-node-checkbox-gap, calc(var(--spacing, .25rem) * 2))}:host .ngs-tree-node-checkbox ngs-checkbox{--ngs-checkbox-gap: 0}:host .ngs-tree-node-checkbox .ngs-checkbox-label{display:none}\n/*! tailwindcss v4.2.2 | MIT License | https://tailwindcss.com */\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
971
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.4", type: TreeNode, isStandalone: true, selector: "ngs-tree-node", inputs: { tabIndexInputBinding: { classPropertyName: "tabIndexInputBinding", publicName: "tabIndex", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { activation: "activation", expandedChange: "expandedChange" }, host: { listeners: { "click": "_handleNodeClick($event)", "dragstart": "_handleDragStart($event)", "dragover": "_handleDragOver($event)", "dragleave": "_handleDragLeave($event)", "drop": "_handleDrop($event)", "dragend": "_handleDragEnd()" }, properties: { "class.ngs-tree-node-selectable": "_isSelectable()", "class.ngs-tree-node-selected": "_isSelected()", "class.ngs-tree-node-disabled": "disabled()", "class.ngs-tree-node-draggable": "_isDraggable()", "class.ngs-tree-node-dragging-source": "_isDraggingSource()", "class.ngs-tree-node-drop-target": "_isDropTarget()", "class.ngs-tree-node-drop-before": "_isDropTargetPosition(\"before\")", "class.ngs-tree-node-drop-inside": "_isDropTargetPosition(\"inside\")", "class.ngs-tree-node-drop-after": "_isDropTargetPosition(\"after\")", "attr.draggable": "_getDraggableAttribute()", "attr.aria-expanded": "_getAriaExpanded()", "attr.aria-level": "level + 1", "attr.aria-posinset": "_getPositionInSet()", "attr.aria-setsize": "_getSetSize()", "attr.aria-selected": "_getAriaSelected()", "attr.aria-disabled": "disabled()", "attr.aria-grabbed": "_getAriaGrabbed()", "tabindex": "_getTabindexAttribute()" }, classAttribute: "ngs-tree-node" }, providers: [{ provide: CdkTreeNode, useExisting: TreeNode }], exportAs: ["ngsTreeNode"], usesInheritance: true, ngImport: i0, template: `<ng-content />`, isInline: true, styles: [":host{color:var(--ngs-tree-node-color);font-size:var(--ngs-tree-node-font-size);position:relative}:host.ngs-tree-node{display:flex;align-items:center;flex:1;gap:var(--ngs-tree-node-gap);padding:var(--ngs-tree-node-padding);word-wrap:break-word;min-height:var(--ngs-tree-node-min-height);box-sizing:border-box}:host.ngs-nested-tree-node{border-bottom-width:0}:host.ngs-tree-node-selectable{border-radius:var(--ngs-tree-node-radius);cursor:pointer}:host.ngs-tree-node-disabled{opacity:var(--ngs-tree-node-disabled-opacity);cursor:default}:host.ngs-tree-node-draggable{cursor:grab}:host.ngs-tree-node-draggable:active{cursor:grabbing}:host.ngs-tree-node-dragging-source{opacity:var(--ngs-tree-node-dragging-source-opacity, .45)}:host.ngs-tree-node-drag-image{position:fixed;inset-block-start:0;inset-inline-start:0;z-index:-1;box-sizing:border-box;border-radius:var(--ngs-tree-node-radius);background:var(--ngs-tree-node-drag-image-bg, var(--ngs-color-surface));box-shadow:var(--ngs-tree-node-drag-image-shadow, var(--ngs-shadow-md));opacity:var(--ngs-tree-node-drag-image-opacity, .96);pointer-events:none;transform:translate(-200vw,-200vh)}:host.ngs-tree-node-drop-inside{color:var(--ngs-tree-node-drop-target-color, var(--ngs-tree-node-active-color));background:var(--ngs-tree-node-drop-target-bg, var(--ngs-tree-node-active-bg));outline:var(--ngs-tree-node-drop-target-outline, 1px solid var(--ngs-color-primary));outline-offset:var(--ngs-tree-node-drop-target-outline-offset, -1px)}:host.ngs-tree-node-drop-before:before,:host.ngs-tree-node-drop-after:after{content:\"\";position:absolute;z-index:1;inset-inline:0;height:var(--ngs-tree-node-drop-line-size, 2px);background:var(--ngs-tree-node-drop-line-color, var(--ngs-color-primary));border-radius:var(--ngs-tree-node-drop-line-radius, 999px);pointer-events:none}:host.ngs-tree-node-drop-before:before{top:0}:host.ngs-tree-node-drop-after:after{bottom:0}:host.ngs-tree-node-selectable:not(.ngs-tree-node-selected,.ngs-tree-node-disabled):hover{color:var(--ngs-tree-node-hover-color);background:var(--ngs-tree-node-hover-bg)}:host.ngs-tree-node-selected:not(.ngs-tree-node-disabled){color:var(--ngs-tree-node-active-color);background:var(--ngs-tree-node-active-bg)}:host.ngs-tree-node-selectable>button:disabled{pointer-events:none}:host .ngs-tree-node-checkbox{display:inline-flex;align-items:center;justify-content:center;flex:none;margin-inline-end:var(--ngs-tree-node-checkbox-gap, calc(var(--spacing, .25rem) * 2))}:host .ngs-tree-node-checkbox ngs-checkbox{--ngs-checkbox-gap: 0}:host .ngs-tree-node-checkbox .ngs-checkbox-label{display:none}\n/*! tailwindcss v4.2.2 | MIT License | https://tailwindcss.com */\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
858
972
  }
859
973
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: TreeNode, decorators: [{
860
974
  type: Component,
861
- args: [{ selector: 'ngs-tree-node', exportAs: 'ngsTreeNode', template: '<ng-content />', standalone: true, outputs: ['activation', 'expandedChange'], providers: [{ provide: CdkTreeNode, useExisting: TreeNode }], changeDetection: ChangeDetectionStrategy.OnPush, host: {
975
+ args: [{ selector: 'ngs-tree-node', exportAs: 'ngsTreeNode', template: `<ng-content />`, standalone: true, outputs: ['activation', 'expandedChange'], providers: [{ provide: CdkTreeNode, useExisting: TreeNode }], changeDetection: ChangeDetectionStrategy.OnPush, host: {
862
976
  'class': 'ngs-tree-node',
863
977
  '[class.ngs-tree-node-selectable]': '_isSelectable()',
864
978
  '[class.ngs-tree-node-selected]': '_isSelected()',
865
979
  '[class.ngs-tree-node-disabled]': 'disabled()',
866
980
  '[class.ngs-tree-node-draggable]': '_isDraggable()',
981
+ '[class.ngs-tree-node-dragging-source]': '_isDraggingSource()',
867
982
  '[class.ngs-tree-node-drop-target]': '_isDropTarget()',
868
983
  '[class.ngs-tree-node-drop-before]': '_isDropTargetPosition("before")',
869
984
  '[class.ngs-tree-node-drop-inside]': '_isDropTargetPosition("inside")',
@@ -883,7 +998,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImpor
883
998
  '(drop)': '_handleDrop($event)',
884
999
  '(dragend)': '_handleDragEnd()',
885
1000
  '[tabindex]': '_getTabindexAttribute()',
886
- }, styles: [":host{color:var(--ngs-tree-node-color);font-size:var(--ngs-tree-node-font-size);position:relative}:host.ngs-tree-node{display:flex;align-items:center;flex:1;gap:var(--ngs-tree-node-gap);padding:var(--ngs-tree-node-padding);word-wrap:break-word;min-height:var(--ngs-tree-node-min-height);box-sizing:border-box}:host.ngs-nested-tree-node{border-bottom-width:0}:host.ngs-tree-node-selectable{border-radius:var(--ngs-tree-node-radius);cursor:pointer}:host.ngs-tree-node-disabled{opacity:var(--ngs-tree-node-disabled-opacity);cursor:default}:host.ngs-tree-node-draggable{cursor:grab}:host.ngs-tree-node-draggable:active{cursor:grabbing}:host.ngs-tree-node-drop-inside{color:var(--ngs-tree-node-drop-target-color, var(--ngs-tree-node-active-color));background:var(--ngs-tree-node-drop-target-bg, var(--ngs-tree-node-active-bg));outline:var(--ngs-tree-node-drop-target-outline, 1px solid var(--ngs-color-primary));outline-offset:var(--ngs-tree-node-drop-target-outline-offset, -1px)}:host.ngs-tree-node-drop-before:before,:host.ngs-tree-node-drop-after:after{content:\"\";position:absolute;z-index:1;inset-inline:0;height:var(--ngs-tree-node-drop-line-size, 2px);background:var(--ngs-tree-node-drop-line-color, var(--ngs-color-primary));border-radius:var(--ngs-tree-node-drop-line-radius, 999px);pointer-events:none}:host.ngs-tree-node-drop-before:before{top:0}:host.ngs-tree-node-drop-after:after{bottom:0}:host.ngs-tree-node-selectable:not(.ngs-tree-node-selected,.ngs-tree-node-disabled):hover{color:var(--ngs-tree-node-hover-color);background:var(--ngs-tree-node-hover-bg)}:host.ngs-tree-node-selected:not(.ngs-tree-node-disabled){color:var(--ngs-tree-node-active-color);background:var(--ngs-tree-node-active-bg)}:host.ngs-tree-node-selectable>button:disabled{pointer-events:none}:host .ngs-tree-node-checkbox{display:inline-flex;align-items:center;justify-content:center;flex:none;margin-inline-end:var(--ngs-tree-node-checkbox-gap, calc(var(--spacing, .25rem) * 2))}:host .ngs-tree-node-checkbox ngs-checkbox{--ngs-checkbox-gap: 0}:host .ngs-tree-node-checkbox .ngs-checkbox-label{display:none}\n/*! tailwindcss v4.2.2 | MIT License | https://tailwindcss.com */\n"] }]
1001
+ }, styles: [":host{color:var(--ngs-tree-node-color);font-size:var(--ngs-tree-node-font-size);position:relative}:host.ngs-tree-node{display:flex;align-items:center;flex:1;gap:var(--ngs-tree-node-gap);padding:var(--ngs-tree-node-padding);word-wrap:break-word;min-height:var(--ngs-tree-node-min-height);box-sizing:border-box}:host.ngs-nested-tree-node{border-bottom-width:0}:host.ngs-tree-node-selectable{border-radius:var(--ngs-tree-node-radius);cursor:pointer}:host.ngs-tree-node-disabled{opacity:var(--ngs-tree-node-disabled-opacity);cursor:default}:host.ngs-tree-node-draggable{cursor:grab}:host.ngs-tree-node-draggable:active{cursor:grabbing}:host.ngs-tree-node-dragging-source{opacity:var(--ngs-tree-node-dragging-source-opacity, .45)}:host.ngs-tree-node-drag-image{position:fixed;inset-block-start:0;inset-inline-start:0;z-index:-1;box-sizing:border-box;border-radius:var(--ngs-tree-node-radius);background:var(--ngs-tree-node-drag-image-bg, var(--ngs-color-surface));box-shadow:var(--ngs-tree-node-drag-image-shadow, var(--ngs-shadow-md));opacity:var(--ngs-tree-node-drag-image-opacity, .96);pointer-events:none;transform:translate(-200vw,-200vh)}:host.ngs-tree-node-drop-inside{color:var(--ngs-tree-node-drop-target-color, var(--ngs-tree-node-active-color));background:var(--ngs-tree-node-drop-target-bg, var(--ngs-tree-node-active-bg));outline:var(--ngs-tree-node-drop-target-outline, 1px solid var(--ngs-color-primary));outline-offset:var(--ngs-tree-node-drop-target-outline-offset, -1px)}:host.ngs-tree-node-drop-before:before,:host.ngs-tree-node-drop-after:after{content:\"\";position:absolute;z-index:1;inset-inline:0;height:var(--ngs-tree-node-drop-line-size, 2px);background:var(--ngs-tree-node-drop-line-color, var(--ngs-color-primary));border-radius:var(--ngs-tree-node-drop-line-radius, 999px);pointer-events:none}:host.ngs-tree-node-drop-before:before{top:0}:host.ngs-tree-node-drop-after:after{bottom:0}:host.ngs-tree-node-selectable:not(.ngs-tree-node-selected,.ngs-tree-node-disabled):hover{color:var(--ngs-tree-node-hover-color);background:var(--ngs-tree-node-hover-bg)}:host.ngs-tree-node-selected:not(.ngs-tree-node-disabled){color:var(--ngs-tree-node-active-color);background:var(--ngs-tree-node-active-bg)}:host.ngs-tree-node-selectable>button:disabled{pointer-events:none}:host .ngs-tree-node-checkbox{display:inline-flex;align-items:center;justify-content:center;flex:none;margin-inline-end:var(--ngs-tree-node-checkbox-gap, calc(var(--spacing, .25rem) * 2))}:host .ngs-tree-node-checkbox ngs-checkbox{--ngs-checkbox-gap: 0}:host .ngs-tree-node-checkbox .ngs-checkbox-label{display:none}\n/*! tailwindcss v4.2.2 | MIT License | https://tailwindcss.com */\n"] }]
887
1002
  }], ctorParameters: () => [], propDecorators: { tabIndexInputBinding: [{ type: i0.Input, args: [{ isSignal: true, alias: "tabIndex", required: false }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }] } });
888
1003
  class NestedTreeNode extends CdkNestedTreeNode {
889
1004
  _hostElementRef = inject(ElementRef);
@@ -949,6 +1064,9 @@ class NestedTreeNode extends CdkNestedTreeNode {
949
1064
  _isDropTargetPosition(position) {
950
1065
  return this._tree._isNodeDropTargetPosition(this.data, position);
951
1066
  }
1067
+ _isDraggingSource() {
1068
+ return this._tree._isNodeDraggingSource(this.data);
1069
+ }
952
1070
  _getDraggableAttribute() {
953
1071
  return this._isDraggable() ? true : null;
954
1072
  }
@@ -957,6 +1075,9 @@ class NestedTreeNode extends CdkNestedTreeNode {
957
1075
  }
958
1076
  _handleDragStart(event) {
959
1077
  this._tree._startNodeDrag(this.data, event);
1078
+ if (!event.defaultPrevented) {
1079
+ this._setDragImage(event);
1080
+ }
960
1081
  }
961
1082
  _handleDragOver(event) {
962
1083
  this._tree._dragNodeOver(this.data, event);
@@ -970,6 +1091,16 @@ class NestedTreeNode extends CdkNestedTreeNode {
970
1091
  _handleDragEnd() {
971
1092
  this._tree._endNodeDrag();
972
1093
  }
1094
+ _setDragImage(event) {
1095
+ if (this._tree._getDragPreview() === 'none') {
1096
+ setEmptyTreeNodeDragImage(event);
1097
+ return;
1098
+ }
1099
+ if (this._tree._setDragPlaceholderImage(this.data, event, this._hostElementRef.nativeElement)) {
1100
+ return;
1101
+ }
1102
+ setTreeNodeDragImage(event, this._hostElementRef.nativeElement);
1103
+ }
973
1104
  _selectNodeFromEvent(event) {
974
1105
  if (!this._isSelectable() || this._isTreeControlClick(event)) {
975
1106
  return;
@@ -1028,15 +1159,15 @@ class NestedTreeNode extends CdkNestedTreeNode {
1028
1159
  super.ngOnDestroy();
1029
1160
  }
1030
1161
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: NestedTreeNode, deps: [], target: i0.ɵɵFactoryTarget.Component });
1031
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.4", type: NestedTreeNode, isStandalone: true, selector: "ngs-nested-tree-node", inputs: { node: { classPropertyName: "node", publicName: "ngsNestedTreeNode", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, tabIndexInput: { classPropertyName: "tabIndexInput", publicName: "tabIndex", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { activation: "activation", expandedChange: "expandedChange" }, host: { listeners: { "click": "_handleNodeClick($event)", "dragstart": "_handleDragStart($event)", "dragover": "_handleDragOver($event)", "dragleave": "_handleDragLeave($event)", "drop": "_handleDrop($event)", "dragend": "_handleDragEnd()" }, properties: { "class.ngs-tree-node-selectable": "_isSelectable()", "class.ngs-tree-node-selected": "_isSelected()", "class.ngs-tree-node-disabled": "disabled()", "class.ngs-tree-node-draggable": "_isDraggable()", "class.ngs-tree-node-drop-target": "_isDropTarget()", "class.ngs-tree-node-drop-before": "_isDropTargetPosition(\"before\")", "class.ngs-tree-node-drop-inside": "_isDropTargetPosition(\"inside\")", "class.ngs-tree-node-drop-after": "_isDropTargetPosition(\"after\")", "attr.draggable": "_getDraggableAttribute()", "attr.aria-selected": "_getAriaSelected()", "attr.aria-disabled": "disabled()", "attr.aria-grabbed": "_getAriaGrabbed()" }, classAttribute: "ngs-nested-tree-node" }, providers: [
1162
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.4", type: NestedTreeNode, isStandalone: true, selector: "ngs-nested-tree-node", inputs: { node: { classPropertyName: "node", publicName: "ngsNestedTreeNode", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, tabIndexInput: { classPropertyName: "tabIndexInput", publicName: "tabIndex", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { activation: "activation", expandedChange: "expandedChange" }, host: { listeners: { "click": "_handleNodeClick($event)", "dragstart": "_handleDragStart($event)", "dragover": "_handleDragOver($event)", "dragleave": "_handleDragLeave($event)", "drop": "_handleDrop($event)", "dragend": "_handleDragEnd()" }, properties: { "class.ngs-tree-node-selectable": "_isSelectable()", "class.ngs-tree-node-selected": "_isSelected()", "class.ngs-tree-node-disabled": "disabled()", "class.ngs-tree-node-draggable": "_isDraggable()", "class.ngs-tree-node-dragging-source": "_isDraggingSource()", "class.ngs-tree-node-drop-target": "_isDropTarget()", "class.ngs-tree-node-drop-before": "_isDropTargetPosition(\"before\")", "class.ngs-tree-node-drop-inside": "_isDropTargetPosition(\"inside\")", "class.ngs-tree-node-drop-after": "_isDropTargetPosition(\"after\")", "attr.draggable": "_getDraggableAttribute()", "attr.aria-selected": "_getAriaSelected()", "attr.aria-disabled": "disabled()", "attr.aria-grabbed": "_getAriaGrabbed()" }, classAttribute: "ngs-nested-tree-node" }, providers: [
1032
1163
  { provide: CdkNestedTreeNode, useExisting: NestedTreeNode },
1033
1164
  { provide: CdkTreeNode, useExisting: NestedTreeNode },
1034
1165
  { provide: CDK_TREE_NODE_OUTLET_NODE, useExisting: NestedTreeNode },
1035
- ], exportAs: ["ngsNestedTreeNode"], usesInheritance: true, ngImport: i0, template: '<ng-content />', isInline: true, styles: [":host{color:var(--ngs-tree-node-color);font-size:var(--ngs-tree-node-font-size);position:relative}:host.ngs-tree-node{display:flex;align-items:center;flex:1;gap:var(--ngs-tree-node-gap);padding:var(--ngs-tree-node-padding);word-wrap:break-word;min-height:var(--ngs-tree-node-min-height);box-sizing:border-box}:host.ngs-nested-tree-node{border-bottom-width:0}:host.ngs-tree-node-selectable{border-radius:var(--ngs-tree-node-radius);cursor:pointer}:host.ngs-tree-node-disabled{opacity:var(--ngs-tree-node-disabled-opacity);cursor:default}:host.ngs-tree-node-draggable{cursor:grab}:host.ngs-tree-node-draggable:active{cursor:grabbing}:host.ngs-tree-node-drop-inside{color:var(--ngs-tree-node-drop-target-color, var(--ngs-tree-node-active-color));background:var(--ngs-tree-node-drop-target-bg, var(--ngs-tree-node-active-bg));outline:var(--ngs-tree-node-drop-target-outline, 1px solid var(--ngs-color-primary));outline-offset:var(--ngs-tree-node-drop-target-outline-offset, -1px)}:host.ngs-tree-node-drop-before:before,:host.ngs-tree-node-drop-after:after{content:\"\";position:absolute;z-index:1;inset-inline:0;height:var(--ngs-tree-node-drop-line-size, 2px);background:var(--ngs-tree-node-drop-line-color, var(--ngs-color-primary));border-radius:var(--ngs-tree-node-drop-line-radius, 999px);pointer-events:none}:host.ngs-tree-node-drop-before:before{top:0}:host.ngs-tree-node-drop-after:after{bottom:0}:host.ngs-tree-node-selectable:not(.ngs-tree-node-selected,.ngs-tree-node-disabled):hover{color:var(--ngs-tree-node-hover-color);background:var(--ngs-tree-node-hover-bg)}:host.ngs-tree-node-selected:not(.ngs-tree-node-disabled){color:var(--ngs-tree-node-active-color);background:var(--ngs-tree-node-active-bg)}:host.ngs-tree-node-selectable>button:disabled{pointer-events:none}:host .ngs-tree-node-checkbox{display:inline-flex;align-items:center;justify-content:center;flex:none;margin-inline-end:var(--ngs-tree-node-checkbox-gap, calc(var(--spacing, .25rem) * 2))}:host .ngs-tree-node-checkbox ngs-checkbox{--ngs-checkbox-gap: 0}:host .ngs-tree-node-checkbox .ngs-checkbox-label{display:none}\n/*! tailwindcss v4.2.2 | MIT License | https://tailwindcss.com */\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1166
+ ], exportAs: ["ngsNestedTreeNode"], usesInheritance: true, ngImport: i0, template: `<ng-content />`, isInline: true, styles: [":host{color:var(--ngs-tree-node-color);font-size:var(--ngs-tree-node-font-size);position:relative}:host.ngs-tree-node{display:flex;align-items:center;flex:1;gap:var(--ngs-tree-node-gap);padding:var(--ngs-tree-node-padding);word-wrap:break-word;min-height:var(--ngs-tree-node-min-height);box-sizing:border-box}:host.ngs-nested-tree-node{border-bottom-width:0}:host.ngs-tree-node-selectable{border-radius:var(--ngs-tree-node-radius);cursor:pointer}:host.ngs-tree-node-disabled{opacity:var(--ngs-tree-node-disabled-opacity);cursor:default}:host.ngs-tree-node-draggable{cursor:grab}:host.ngs-tree-node-draggable:active{cursor:grabbing}:host.ngs-tree-node-dragging-source{opacity:var(--ngs-tree-node-dragging-source-opacity, .45)}:host.ngs-tree-node-drag-image{position:fixed;inset-block-start:0;inset-inline-start:0;z-index:-1;box-sizing:border-box;border-radius:var(--ngs-tree-node-radius);background:var(--ngs-tree-node-drag-image-bg, var(--ngs-color-surface));box-shadow:var(--ngs-tree-node-drag-image-shadow, var(--ngs-shadow-md));opacity:var(--ngs-tree-node-drag-image-opacity, .96);pointer-events:none;transform:translate(-200vw,-200vh)}:host.ngs-tree-node-drop-inside{color:var(--ngs-tree-node-drop-target-color, var(--ngs-tree-node-active-color));background:var(--ngs-tree-node-drop-target-bg, var(--ngs-tree-node-active-bg));outline:var(--ngs-tree-node-drop-target-outline, 1px solid var(--ngs-color-primary));outline-offset:var(--ngs-tree-node-drop-target-outline-offset, -1px)}:host.ngs-tree-node-drop-before:before,:host.ngs-tree-node-drop-after:after{content:\"\";position:absolute;z-index:1;inset-inline:0;height:var(--ngs-tree-node-drop-line-size, 2px);background:var(--ngs-tree-node-drop-line-color, var(--ngs-color-primary));border-radius:var(--ngs-tree-node-drop-line-radius, 999px);pointer-events:none}:host.ngs-tree-node-drop-before:before{top:0}:host.ngs-tree-node-drop-after:after{bottom:0}:host.ngs-tree-node-selectable:not(.ngs-tree-node-selected,.ngs-tree-node-disabled):hover{color:var(--ngs-tree-node-hover-color);background:var(--ngs-tree-node-hover-bg)}:host.ngs-tree-node-selected:not(.ngs-tree-node-disabled){color:var(--ngs-tree-node-active-color);background:var(--ngs-tree-node-active-bg)}:host.ngs-tree-node-selectable>button:disabled{pointer-events:none}:host .ngs-tree-node-checkbox{display:inline-flex;align-items:center;justify-content:center;flex:none;margin-inline-end:var(--ngs-tree-node-checkbox-gap, calc(var(--spacing, .25rem) * 2))}:host .ngs-tree-node-checkbox ngs-checkbox{--ngs-checkbox-gap: 0}:host .ngs-tree-node-checkbox .ngs-checkbox-label{display:none}\n/*! tailwindcss v4.2.2 | MIT License | https://tailwindcss.com */\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1036
1167
  }
1037
1168
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: NestedTreeNode, decorators: [{
1038
1169
  type: Component,
1039
- args: [{ selector: 'ngs-nested-tree-node', exportAs: 'ngsNestedTreeNode', template: '<ng-content />', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, outputs: ['activation', 'expandedChange'], providers: [
1170
+ args: [{ selector: 'ngs-nested-tree-node', exportAs: 'ngsNestedTreeNode', template: `<ng-content />`, standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, outputs: ['activation', 'expandedChange'], providers: [
1040
1171
  { provide: CdkNestedTreeNode, useExisting: NestedTreeNode },
1041
1172
  { provide: CdkTreeNode, useExisting: NestedTreeNode },
1042
1173
  { provide: CDK_TREE_NODE_OUTLET_NODE, useExisting: NestedTreeNode },
@@ -1046,6 +1177,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImpor
1046
1177
  '[class.ngs-tree-node-selected]': '_isSelected()',
1047
1178
  '[class.ngs-tree-node-disabled]': 'disabled()',
1048
1179
  '[class.ngs-tree-node-draggable]': '_isDraggable()',
1180
+ '[class.ngs-tree-node-dragging-source]': '_isDraggingSource()',
1049
1181
  '[class.ngs-tree-node-drop-target]': '_isDropTarget()',
1050
1182
  '[class.ngs-tree-node-drop-before]': '_isDropTargetPosition("before")',
1051
1183
  '[class.ngs-tree-node-drop-inside]': '_isDropTargetPosition("inside")',
@@ -1060,7 +1192,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImpor
1060
1192
  '(dragleave)': '_handleDragLeave($event)',
1061
1193
  '(drop)': '_handleDrop($event)',
1062
1194
  '(dragend)': '_handleDragEnd()',
1063
- }, styles: [":host{color:var(--ngs-tree-node-color);font-size:var(--ngs-tree-node-font-size);position:relative}:host.ngs-tree-node{display:flex;align-items:center;flex:1;gap:var(--ngs-tree-node-gap);padding:var(--ngs-tree-node-padding);word-wrap:break-word;min-height:var(--ngs-tree-node-min-height);box-sizing:border-box}:host.ngs-nested-tree-node{border-bottom-width:0}:host.ngs-tree-node-selectable{border-radius:var(--ngs-tree-node-radius);cursor:pointer}:host.ngs-tree-node-disabled{opacity:var(--ngs-tree-node-disabled-opacity);cursor:default}:host.ngs-tree-node-draggable{cursor:grab}:host.ngs-tree-node-draggable:active{cursor:grabbing}:host.ngs-tree-node-drop-inside{color:var(--ngs-tree-node-drop-target-color, var(--ngs-tree-node-active-color));background:var(--ngs-tree-node-drop-target-bg, var(--ngs-tree-node-active-bg));outline:var(--ngs-tree-node-drop-target-outline, 1px solid var(--ngs-color-primary));outline-offset:var(--ngs-tree-node-drop-target-outline-offset, -1px)}:host.ngs-tree-node-drop-before:before,:host.ngs-tree-node-drop-after:after{content:\"\";position:absolute;z-index:1;inset-inline:0;height:var(--ngs-tree-node-drop-line-size, 2px);background:var(--ngs-tree-node-drop-line-color, var(--ngs-color-primary));border-radius:var(--ngs-tree-node-drop-line-radius, 999px);pointer-events:none}:host.ngs-tree-node-drop-before:before{top:0}:host.ngs-tree-node-drop-after:after{bottom:0}:host.ngs-tree-node-selectable:not(.ngs-tree-node-selected,.ngs-tree-node-disabled):hover{color:var(--ngs-tree-node-hover-color);background:var(--ngs-tree-node-hover-bg)}:host.ngs-tree-node-selected:not(.ngs-tree-node-disabled){color:var(--ngs-tree-node-active-color);background:var(--ngs-tree-node-active-bg)}:host.ngs-tree-node-selectable>button:disabled{pointer-events:none}:host .ngs-tree-node-checkbox{display:inline-flex;align-items:center;justify-content:center;flex:none;margin-inline-end:var(--ngs-tree-node-checkbox-gap, calc(var(--spacing, .25rem) * 2))}:host .ngs-tree-node-checkbox ngs-checkbox{--ngs-checkbox-gap: 0}:host .ngs-tree-node-checkbox .ngs-checkbox-label{display:none}\n/*! tailwindcss v4.2.2 | MIT License | https://tailwindcss.com */\n"] }]
1195
+ }, styles: [":host{color:var(--ngs-tree-node-color);font-size:var(--ngs-tree-node-font-size);position:relative}:host.ngs-tree-node{display:flex;align-items:center;flex:1;gap:var(--ngs-tree-node-gap);padding:var(--ngs-tree-node-padding);word-wrap:break-word;min-height:var(--ngs-tree-node-min-height);box-sizing:border-box}:host.ngs-nested-tree-node{border-bottom-width:0}:host.ngs-tree-node-selectable{border-radius:var(--ngs-tree-node-radius);cursor:pointer}:host.ngs-tree-node-disabled{opacity:var(--ngs-tree-node-disabled-opacity);cursor:default}:host.ngs-tree-node-draggable{cursor:grab}:host.ngs-tree-node-draggable:active{cursor:grabbing}:host.ngs-tree-node-dragging-source{opacity:var(--ngs-tree-node-dragging-source-opacity, .45)}:host.ngs-tree-node-drag-image{position:fixed;inset-block-start:0;inset-inline-start:0;z-index:-1;box-sizing:border-box;border-radius:var(--ngs-tree-node-radius);background:var(--ngs-tree-node-drag-image-bg, var(--ngs-color-surface));box-shadow:var(--ngs-tree-node-drag-image-shadow, var(--ngs-shadow-md));opacity:var(--ngs-tree-node-drag-image-opacity, .96);pointer-events:none;transform:translate(-200vw,-200vh)}:host.ngs-tree-node-drop-inside{color:var(--ngs-tree-node-drop-target-color, var(--ngs-tree-node-active-color));background:var(--ngs-tree-node-drop-target-bg, var(--ngs-tree-node-active-bg));outline:var(--ngs-tree-node-drop-target-outline, 1px solid var(--ngs-color-primary));outline-offset:var(--ngs-tree-node-drop-target-outline-offset, -1px)}:host.ngs-tree-node-drop-before:before,:host.ngs-tree-node-drop-after:after{content:\"\";position:absolute;z-index:1;inset-inline:0;height:var(--ngs-tree-node-drop-line-size, 2px);background:var(--ngs-tree-node-drop-line-color, var(--ngs-color-primary));border-radius:var(--ngs-tree-node-drop-line-radius, 999px);pointer-events:none}:host.ngs-tree-node-drop-before:before{top:0}:host.ngs-tree-node-drop-after:after{bottom:0}:host.ngs-tree-node-selectable:not(.ngs-tree-node-selected,.ngs-tree-node-disabled):hover{color:var(--ngs-tree-node-hover-color);background:var(--ngs-tree-node-hover-bg)}:host.ngs-tree-node-selected:not(.ngs-tree-node-disabled){color:var(--ngs-tree-node-active-color);background:var(--ngs-tree-node-active-bg)}:host.ngs-tree-node-selectable>button:disabled{pointer-events:none}:host .ngs-tree-node-checkbox{display:inline-flex;align-items:center;justify-content:center;flex:none;margin-inline-end:var(--ngs-tree-node-checkbox-gap, calc(var(--spacing, .25rem) * 2))}:host .ngs-tree-node-checkbox ngs-checkbox{--ngs-checkbox-gap: 0}:host .ngs-tree-node-checkbox .ngs-checkbox-label{display:none}\n/*! tailwindcss v4.2.2 | MIT License | https://tailwindcss.com */\n"] }]
1064
1196
  }], ctorParameters: () => [], propDecorators: { node: [{ type: i0.Input, args: [{ isSignal: true, alias: "ngsNestedTreeNode", required: false }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], tabIndexInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "tabIndex", required: false }] }] } });
1065
1197
 
1066
1198
  class TreeNodePadding extends CdkTreeNodePadding {
@@ -1121,5 +1253,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImpor
1121
1253
  * Generated bundle index. Do not edit.
1122
1254
  */
1123
1255
 
1124
- export { NestedTreeNode, Tree, TreeNode, TreeNodeDef, TreeNodeOutlet, TreeNodePadding, TreeNodeToggle };
1256
+ export { NestedTreeNode, Tree, TreeDragPlaceholder, TreeNode, TreeNodeDef, TreeNodeOutlet, TreeNodePadding, TreeNodeToggle };
1125
1257
  //# sourceMappingURL=ngstarter-ui-components-tree.mjs.map