@ngstarter-ui/components 21.0.39 → 21.0.41

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,11 @@ 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 */ []));
78
+ nodePaddingIndent = input(48, ...(ngDevMode ? [{ debugName: "nodePaddingIndent" }] : /* istanbul ignore next */ []));
59
79
  childrenKey = input('children', ...(ngDevMode ? [{ debugName: "childrenKey" }] : /* istanbul ignore next */ []));
60
80
  filterValue = input('', { ...(ngDevMode ? { debugName: "filterValue" } : /* istanbul ignore next */ {}), transform: (value) => value == null ? '' : String(value) });
61
81
  filterPredicate = input(NGS_TREE_DEFAULT_FILTER_PREDICATE, ...(ngDevMode ? [{ debugName: "filterPredicate" }] : /* istanbul ignore next */ []));
@@ -67,6 +87,7 @@ class Tree extends CdkTree {
67
87
  _selectedKey = signal(undefined, ...(ngDevMode ? [{ debugName: "_selectedKey" }] : /* istanbul ignore next */ []));
68
88
  _dropTargetKey = signal(undefined, ...(ngDevMode ? [{ debugName: "_dropTargetKey" }] : /* istanbul ignore next */ []));
69
89
  _dropTargetPosition = signal(undefined, ...(ngDevMode ? [{ debugName: "_dropTargetPosition" }] : /* istanbul ignore next */ []));
90
+ _draggedNodeKey = signal(undefined, ...(ngDevMode ? [{ debugName: "_draggedNodeKey" }] : /* istanbul ignore next */ []));
70
91
  _checkedKeys = new Set();
71
92
  _nodeValueByDataKey = new Map();
72
93
  _disabledDataKeys = new Set();
@@ -74,6 +95,7 @@ class Tree extends CdkTree {
74
95
  _draggedNode;
75
96
  _sourceDataSource;
76
97
  _filteredNodeOriginals = new WeakMap();
98
+ _dragPlaceholder;
77
99
  _nodeOutlet = undefined;
78
100
  constructor() {
79
101
  super();
@@ -138,7 +160,10 @@ class Tree extends CdkTree {
138
160
  return !this._isNodeDisabled(node) && Object.is(this._selectedKey(), this._getTreeNodeValue(node));
139
161
  }
140
162
  _canDragNode(node) {
141
- return node !== undefined && this.draggable() && !this._isNodeDisabled(node);
163
+ return node !== undefined
164
+ && this.draggable()
165
+ && !this._isNodeDisabled(node)
166
+ && this.draggablePredicate()(node);
142
167
  }
143
168
  _isNodeDropTarget(node) {
144
169
  return node !== undefined && Object.is(this._dropTargetKey(), this._getTreeNodeDataKey(node));
@@ -146,12 +171,16 @@ class Tree extends CdkTree {
146
171
  _isNodeDropTargetPosition(node, position) {
147
172
  return this._isNodeDropTarget(node) && this._dropTargetPosition() === position;
148
173
  }
174
+ _isNodeDraggingSource(node) {
175
+ return node !== undefined && Object.is(this._draggedNodeKey(), this._getTreeNodeDataKey(node));
176
+ }
149
177
  _startNodeDrag(node, event) {
150
178
  if (!this._canDragNode(node)) {
151
179
  event.preventDefault();
152
180
  return;
153
181
  }
154
182
  this._draggedNode = node;
183
+ this._draggedNodeKey.set(this._getTreeNodeDataKey(node));
155
184
  if (event.dataTransfer) {
156
185
  event.dataTransfer.effectAllowed = 'move';
157
186
  event.dataTransfer.setData('text/plain', String(this._getTreeNodeValue(node) ?? ''));
@@ -185,7 +214,7 @@ class Tree extends CdkTree {
185
214
  event.preventDefault();
186
215
  event.stopPropagation();
187
216
  const source = this._draggedNode;
188
- const moved = this._moveNode(source, node, position);
217
+ const moved = this.reorderOnDrop() ? this._moveNode(source, node, position) : true;
189
218
  this._clearNodeDrag();
190
219
  if (moved) {
191
220
  this.nodeDrop.emit({
@@ -201,6 +230,45 @@ class Tree extends CdkTree {
201
230
  _endNodeDrag() {
202
231
  this._clearNodeDrag();
203
232
  }
233
+ _getDragPreview() {
234
+ return this.dragPreview();
235
+ }
236
+ _hasDragPlaceholder() {
237
+ return !!this._dragPlaceholder;
238
+ }
239
+ _setDragPlaceholderImage(node, event, host) {
240
+ const template = this._dragPlaceholder?.templateRef;
241
+ const dataTransfer = event.dataTransfer;
242
+ const body = host.ownerDocument.body;
243
+ if (!template || !dataTransfer || !body) {
244
+ return false;
245
+ }
246
+ const viewRef = template.createEmbeddedView({
247
+ $implicit: node,
248
+ source: node,
249
+ });
250
+ viewRef.detectChanges();
251
+ const dragImage = host.ownerDocument.createElement('div');
252
+ dragImage.classList.add('ngs-tree-drag-placeholder-image');
253
+ dragImage.style.position = 'fixed';
254
+ dragImage.style.insetBlockStart = '0';
255
+ dragImage.style.insetInlineStart = '0';
256
+ dragImage.style.zIndex = '-1';
257
+ dragImage.style.pointerEvents = 'none';
258
+ dragImage.style.transform = 'translate(-200vw, -200vh)';
259
+ for (const rootNode of viewRef.rootNodes) {
260
+ if (rootNode instanceof Node) {
261
+ dragImage.appendChild(rootNode);
262
+ }
263
+ }
264
+ body.appendChild(dragImage);
265
+ dataTransfer.setDragImage(dragImage, 12, 12);
266
+ window.setTimeout(() => {
267
+ viewRef.destroy();
268
+ dragImage.remove();
269
+ });
270
+ return true;
271
+ }
204
272
  _registerNodeValue(node, value) {
205
273
  const key = this._getTreeNodeDataKey(node);
206
274
  this._nodeValueByDataKey.set(key, value);
@@ -255,7 +323,8 @@ class Tree extends CdkTree {
255
323
  && this.draggable()
256
324
  && !this._isNodeDisabled(target)
257
325
  && !this._isSameNode(source, target)
258
- && !this._isNodeDescendantOf(target, source);
326
+ && !this._isNodeDescendantOf(target, source)
327
+ && this.dropPredicate()(source, target, position);
259
328
  }
260
329
  _moveNode(source, target, position) {
261
330
  const rootNodes = this._getRootNodes();
@@ -455,6 +524,7 @@ class Tree extends CdkTree {
455
524
  }
456
525
  _clearNodeDrag() {
457
526
  this._draggedNode = undefined;
527
+ this._draggedNodeKey.set(undefined);
458
528
  this._dropTargetKey.set(undefined);
459
529
  this._dropTargetPosition.set(undefined);
460
530
  }
@@ -573,7 +643,7 @@ class Tree extends CdkTree {
573
643
  return node;
574
644
  }
575
645
  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 });
646
+ 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 }, nodePaddingIndent: { classPropertyName: "nodePaddingIndent", publicName: "nodePaddingIndent", 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: 0;--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
647
  }
578
648
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: Tree, decorators: [{
579
649
  type: Component,
@@ -581,8 +651,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImpor
581
651
  TreeNodeOutlet
582
652
  ], template: `<ng-container ngsTreeNodeOutlet />`, changeDetection: ChangeDetectionStrategy.OnPush, providers: [{ provide: CdkTree, useExisting: Tree }], host: {
583
653
  'class': 'ngs-tree',
584
- }, 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
+ }, styles: [":host{--ngs-tree-padding: calc(var(--spacing, .25rem) * 3) 0;--ngs-tree-node-padding: 0;--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"] }]
655
+ }], 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 }] }], nodePaddingIndent: [{ type: i0.Input, args: [{ isSignal: true, alias: "nodePaddingIndent", 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: [{
656
+ type: ContentChild,
657
+ args: [TreeDragPlaceholder]
658
+ }], _nodeOutlet: [{
586
659
  type: ViewChild,
587
660
  args: [TreeNodeOutlet, { static: true }]
588
661
  }] } });
@@ -599,6 +672,32 @@ function isTreeNodeControlClick(event, host) {
599
672
  const control = target.closest('.ngs-tree-node-checkbox, [ngsTreeNodeToggle], [ngstreenodetoggle]');
600
673
  return !!control && control !== host;
601
674
  }
675
+ function setTreeNodeDragImage(event, host) {
676
+ const dataTransfer = event.dataTransfer;
677
+ const body = host.ownerDocument.body;
678
+ if (!dataTransfer || !body) {
679
+ return;
680
+ }
681
+ const rect = host.getBoundingClientRect();
682
+ const clone = host.cloneNode(true);
683
+ if (!(clone instanceof HTMLElement)) {
684
+ return;
685
+ }
686
+ clone.classList.add('ngs-tree-node-drag-image');
687
+ clone.style.width = `${rect.width}px`;
688
+ body.appendChild(clone);
689
+ 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)));
690
+ window.setTimeout(() => clone.remove());
691
+ }
692
+ function setEmptyTreeNodeDragImage(event) {
693
+ const dataTransfer = event.dataTransfer;
694
+ if (!dataTransfer) {
695
+ return;
696
+ }
697
+ const image = new Image();
698
+ image.src = 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==';
699
+ dataTransfer.setDragImage(image, 0, 0);
700
+ }
602
701
  class TreeNodeCheckbox {
603
702
  _node;
604
703
  _tree;
@@ -778,6 +877,9 @@ class TreeNode extends CdkTreeNode {
778
877
  _isDropTargetPosition(position) {
779
878
  return this._tree._isNodeDropTargetPosition(this.data, position);
780
879
  }
880
+ _isDraggingSource() {
881
+ return this._tree._isNodeDraggingSource(this.data);
882
+ }
781
883
  _getDraggableAttribute() {
782
884
  return this._isDraggable() ? true : null;
783
885
  }
@@ -786,6 +888,9 @@ class TreeNode extends CdkTreeNode {
786
888
  }
787
889
  _handleDragStart(event) {
788
890
  this._tree._startNodeDrag(this.data, event);
891
+ if (!event.defaultPrevented) {
892
+ this._setDragImage(event);
893
+ }
789
894
  }
790
895
  _handleDragOver(event) {
791
896
  this._tree._dragNodeOver(this.data, event);
@@ -799,6 +904,16 @@ class TreeNode extends CdkTreeNode {
799
904
  _handleDragEnd() {
800
905
  this._tree._endNodeDrag();
801
906
  }
907
+ _setDragImage(event) {
908
+ if (this._tree._getDragPreview() === 'none') {
909
+ setEmptyTreeNodeDragImage(event);
910
+ return;
911
+ }
912
+ if (this._tree._setDragPlaceholderImage(this.data, event, this._hostElementRef.nativeElement)) {
913
+ return;
914
+ }
915
+ setTreeNodeDragImage(event, this._hostElementRef.nativeElement);
916
+ }
802
917
  _selectNodeFromEvent(event) {
803
918
  if (!this._isSelectable() || this._isTreeControlClick(event)) {
804
919
  return;
@@ -854,16 +969,17 @@ class TreeNode extends CdkTreeNode {
854
969
  super.ngOnDestroy();
855
970
  }
856
971
  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 });
972
+ 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
973
  }
859
974
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: TreeNode, decorators: [{
860
975
  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: {
976
+ 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
977
  'class': 'ngs-tree-node',
863
978
  '[class.ngs-tree-node-selectable]': '_isSelectable()',
864
979
  '[class.ngs-tree-node-selected]': '_isSelected()',
865
980
  '[class.ngs-tree-node-disabled]': 'disabled()',
866
981
  '[class.ngs-tree-node-draggable]': '_isDraggable()',
982
+ '[class.ngs-tree-node-dragging-source]': '_isDraggingSource()',
867
983
  '[class.ngs-tree-node-drop-target]': '_isDropTarget()',
868
984
  '[class.ngs-tree-node-drop-before]': '_isDropTargetPosition("before")',
869
985
  '[class.ngs-tree-node-drop-inside]': '_isDropTargetPosition("inside")',
@@ -883,7 +999,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImpor
883
999
  '(drop)': '_handleDrop($event)',
884
1000
  '(dragend)': '_handleDragEnd()',
885
1001
  '[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"] }]
1002
+ }, 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
1003
  }], 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
1004
  class NestedTreeNode extends CdkNestedTreeNode {
889
1005
  _hostElementRef = inject(ElementRef);
@@ -949,6 +1065,9 @@ class NestedTreeNode extends CdkNestedTreeNode {
949
1065
  _isDropTargetPosition(position) {
950
1066
  return this._tree._isNodeDropTargetPosition(this.data, position);
951
1067
  }
1068
+ _isDraggingSource() {
1069
+ return this._tree._isNodeDraggingSource(this.data);
1070
+ }
952
1071
  _getDraggableAttribute() {
953
1072
  return this._isDraggable() ? true : null;
954
1073
  }
@@ -957,6 +1076,9 @@ class NestedTreeNode extends CdkNestedTreeNode {
957
1076
  }
958
1077
  _handleDragStart(event) {
959
1078
  this._tree._startNodeDrag(this.data, event);
1079
+ if (!event.defaultPrevented) {
1080
+ this._setDragImage(event);
1081
+ }
960
1082
  }
961
1083
  _handleDragOver(event) {
962
1084
  this._tree._dragNodeOver(this.data, event);
@@ -970,6 +1092,16 @@ class NestedTreeNode extends CdkNestedTreeNode {
970
1092
  _handleDragEnd() {
971
1093
  this._tree._endNodeDrag();
972
1094
  }
1095
+ _setDragImage(event) {
1096
+ if (this._tree._getDragPreview() === 'none') {
1097
+ setEmptyTreeNodeDragImage(event);
1098
+ return;
1099
+ }
1100
+ if (this._tree._setDragPlaceholderImage(this.data, event, this._hostElementRef.nativeElement)) {
1101
+ return;
1102
+ }
1103
+ setTreeNodeDragImage(event, this._hostElementRef.nativeElement);
1104
+ }
973
1105
  _selectNodeFromEvent(event) {
974
1106
  if (!this._isSelectable() || this._isTreeControlClick(event)) {
975
1107
  return;
@@ -1028,15 +1160,15 @@ class NestedTreeNode extends CdkNestedTreeNode {
1028
1160
  super.ngOnDestroy();
1029
1161
  }
1030
1162
  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: [
1163
+ 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
1164
  { provide: CdkNestedTreeNode, useExisting: NestedTreeNode },
1033
1165
  { provide: CdkTreeNode, useExisting: NestedTreeNode },
1034
1166
  { 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 });
1167
+ ], 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
1168
  }
1037
1169
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: NestedTreeNode, decorators: [{
1038
1170
  type: Component,
1039
- args: [{ selector: 'ngs-nested-tree-node', exportAs: 'ngsNestedTreeNode', template: '<ng-content />', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, outputs: ['activation', 'expandedChange'], providers: [
1171
+ args: [{ selector: 'ngs-nested-tree-node', exportAs: 'ngsNestedTreeNode', template: `<ng-content />`, standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, outputs: ['activation', 'expandedChange'], providers: [
1040
1172
  { provide: CdkNestedTreeNode, useExisting: NestedTreeNode },
1041
1173
  { provide: CdkTreeNode, useExisting: NestedTreeNode },
1042
1174
  { provide: CDK_TREE_NODE_OUTLET_NODE, useExisting: NestedTreeNode },
@@ -1046,6 +1178,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImpor
1046
1178
  '[class.ngs-tree-node-selected]': '_isSelected()',
1047
1179
  '[class.ngs-tree-node-disabled]': 'disabled()',
1048
1180
  '[class.ngs-tree-node-draggable]': '_isDraggable()',
1181
+ '[class.ngs-tree-node-dragging-source]': '_isDraggingSource()',
1049
1182
  '[class.ngs-tree-node-drop-target]': '_isDropTarget()',
1050
1183
  '[class.ngs-tree-node-drop-before]': '_isDropTargetPosition("before")',
1051
1184
  '[class.ngs-tree-node-drop-inside]': '_isDropTargetPosition("inside")',
@@ -1060,20 +1193,21 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImpor
1060
1193
  '(dragleave)': '_handleDragLeave($event)',
1061
1194
  '(drop)': '_handleDrop($event)',
1062
1195
  '(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"] }]
1196
+ }, 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
1197
  }], 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
1198
 
1066
1199
  class TreeNodePadding extends CdkTreeNodePadding {
1200
+ tree = inject(Tree, { optional: true });
1067
1201
  levelInput = input(0, { ...(ngDevMode ? { debugName: "levelInput" } : /* istanbul ignore next */ {}), alias: 'ngsTreeNodePadding',
1068
1202
  transform: numberAttribute });
1069
- indentInput = input(40, { ...(ngDevMode ? { debugName: "indentInput" } : /* istanbul ignore next */ {}), alias: 'ngsTreeNodePaddingIndent' });
1203
+ indentInput = input(undefined, { ...(ngDevMode ? { debugName: "indentInput" } : /* istanbul ignore next */ {}), alias: 'ngsTreeNodePaddingIndent' });
1070
1204
  constructor() {
1071
1205
  super();
1072
1206
  effect(() => {
1073
1207
  this.level = this.levelInput();
1074
1208
  });
1075
1209
  effect(() => {
1076
- this._setIndentInput(this.indentInput());
1210
+ this._setIndentInput(this.indentInput() ?? this.tree?.nodePaddingIndent() ?? 48);
1077
1211
  });
1078
1212
  }
1079
1213
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: TreeNodePadding, deps: [], target: i0.ɵɵFactoryTarget.Directive });
@@ -1121,5 +1255,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImpor
1121
1255
  * Generated bundle index. Do not edit.
1122
1256
  */
1123
1257
 
1124
- export { NestedTreeNode, Tree, TreeNode, TreeNodeDef, TreeNodeOutlet, TreeNodePadding, TreeNodeToggle };
1258
+ export { NestedTreeNode, Tree, TreeDragPlaceholder, TreeNode, TreeNodeDef, TreeNodeOutlet, TreeNodePadding, TreeNodeToggle };
1125
1259
  //# sourceMappingURL=ngstarter-ui-components-tree.mjs.map