@igo2/common 20.1.0-next.9 → 21.0.0-next.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (105) hide show
  1. package/fesm2022/igo2-common-action.mjs +44 -52
  2. package/fesm2022/igo2-common-action.mjs.map +1 -1
  3. package/fesm2022/igo2-common-backdrop.mjs +8 -9
  4. package/fesm2022/igo2-common-backdrop.mjs.map +1 -1
  5. package/fesm2022/igo2-common-badge.mjs +7 -8
  6. package/fesm2022/igo2-common-badge.mjs.map +1 -1
  7. package/fesm2022/igo2-common-clickout.mjs +11 -11
  8. package/fesm2022/igo2-common-clickout.mjs.map +1 -1
  9. package/fesm2022/igo2-common-clone.mjs +8 -9
  10. package/fesm2022/igo2-common-clone.mjs.map +1 -1
  11. package/fesm2022/igo2-common-collapsible.mjs +13 -14
  12. package/fesm2022/igo2-common-collapsible.mjs.map +1 -1
  13. package/fesm2022/igo2-common-color.mjs +9 -9
  14. package/fesm2022/igo2-common-color.mjs.map +1 -1
  15. package/fesm2022/igo2-common-confirm-dialog.mjs +10 -10
  16. package/fesm2022/igo2-common-context-menu.mjs +20 -26
  17. package/fesm2022/igo2-common-context-menu.mjs.map +1 -1
  18. package/fesm2022/igo2-common-custom-html.mjs +11 -12
  19. package/fesm2022/igo2-common-custom-html.mjs.map +1 -1
  20. package/fesm2022/igo2-common-datepicker.mjs +13 -13
  21. package/fesm2022/igo2-common-datepicker.mjs.map +1 -1
  22. package/fesm2022/igo2-common-dom.mjs +7 -7
  23. package/fesm2022/igo2-common-drag-drop.mjs +247 -135
  24. package/fesm2022/igo2-common-drag-drop.mjs.map +1 -1
  25. package/fesm2022/igo2-common-dynamic-component.mjs +19 -19
  26. package/fesm2022/igo2-common-dynamic-component.mjs.map +1 -1
  27. package/fesm2022/igo2-common-entity.mjs +58 -60
  28. package/fesm2022/igo2-common-entity.mjs.map +1 -1
  29. package/fesm2022/igo2-common-flexible.mjs +9 -9
  30. package/fesm2022/igo2-common-flexible.mjs.map +1 -1
  31. package/fesm2022/igo2-common-form.mjs +75 -75
  32. package/fesm2022/igo2-common-form.mjs.map +1 -1
  33. package/fesm2022/igo2-common-home-button.mjs +7 -7
  34. package/fesm2022/igo2-common-icon.mjs +17 -21
  35. package/fesm2022/igo2-common-icon.mjs.map +1 -1
  36. package/fesm2022/igo2-common-image.mjs +14 -16
  37. package/fesm2022/igo2-common-image.mjs.map +1 -1
  38. package/fesm2022/igo2-common-interactive-tour.mjs +16 -16
  39. package/fesm2022/igo2-common-interactive-tour.mjs.map +1 -1
  40. package/fesm2022/igo2-common-json-dialog.mjs +10 -10
  41. package/fesm2022/igo2-common-keyvalue.mjs +8 -9
  42. package/fesm2022/igo2-common-keyvalue.mjs.map +1 -1
  43. package/fesm2022/igo2-common-list.mjs +17 -25
  44. package/fesm2022/igo2-common-list.mjs.map +1 -1
  45. package/fesm2022/igo2-common-panel.mjs +12 -13
  46. package/fesm2022/igo2-common-panel.mjs.map +1 -1
  47. package/fesm2022/igo2-common-resizable-bar.mjs +9 -13
  48. package/fesm2022/igo2-common-resizable-bar.mjs.map +1 -1
  49. package/fesm2022/igo2-common-select-value-dialog.mjs +10 -10
  50. package/fesm2022/igo2-common-select-value-dialog.mjs.map +1 -1
  51. package/fesm2022/igo2-common-sidenav.mjs +14 -19
  52. package/fesm2022/igo2-common-sidenav.mjs.map +1 -1
  53. package/fesm2022/igo2-common-spinner.mjs +13 -14
  54. package/fesm2022/igo2-common-spinner.mjs.map +1 -1
  55. package/fesm2022/igo2-common-stop-propagation.mjs +12 -14
  56. package/fesm2022/igo2-common-stop-propagation.mjs.map +1 -1
  57. package/fesm2022/igo2-common-table.mjs +12 -12
  58. package/fesm2022/igo2-common-table.mjs.map +1 -1
  59. package/fesm2022/igo2-common-timepicker.mjs +9 -9
  60. package/fesm2022/igo2-common-timepicker.mjs.map +1 -1
  61. package/fesm2022/igo2-common-tool.mjs +20 -20
  62. package/fesm2022/igo2-common-tool.mjs.map +1 -1
  63. package/fesm2022/igo2-common-widget.mjs +17 -17
  64. package/fesm2022/igo2-common-widget.mjs.map +1 -1
  65. package/fesm2022/igo2-common-workspace.mjs +21 -21
  66. package/fesm2022/igo2-common-workspace.mjs.map +1 -1
  67. package/package.json +60 -59
  68. package/src/style/partial/common.variables.scss +0 -1
  69. package/{badge/index.d.ts → types/igo2-common-badge.d.ts} +1 -1
  70. package/{clickout/index.d.ts → types/igo2-common-clickout.d.ts} +1 -1
  71. package/{drag-drop/index.d.ts → types/igo2-common-drag-drop.d.ts} +49 -36
  72. package/{entity/index.d.ts → types/igo2-common-entity.d.ts} +1 -1
  73. package/{icon/index.d.ts → types/igo2-common-icon.d.ts} +3 -3
  74. /package/{action/index.d.ts → types/igo2-common-action.d.ts} +0 -0
  75. /package/{backdrop/index.d.ts → types/igo2-common-backdrop.d.ts} +0 -0
  76. /package/{clone/index.d.ts → types/igo2-common-clone.d.ts} +0 -0
  77. /package/{collapsible/index.d.ts → types/igo2-common-collapsible.d.ts} +0 -0
  78. /package/{color/index.d.ts → types/igo2-common-color.d.ts} +0 -0
  79. /package/{confirm-dialog/index.d.ts → types/igo2-common-confirm-dialog.d.ts} +0 -0
  80. /package/{context-menu/index.d.ts → types/igo2-common-context-menu.d.ts} +0 -0
  81. /package/{custom-html/index.d.ts → types/igo2-common-custom-html.d.ts} +0 -0
  82. /package/{datepicker/index.d.ts → types/igo2-common-datepicker.d.ts} +0 -0
  83. /package/{dom/index.d.ts → types/igo2-common-dom.d.ts} +0 -0
  84. /package/{dynamic-component/index.d.ts → types/igo2-common-dynamic-component.d.ts} +0 -0
  85. /package/{environment/index.d.ts → types/igo2-common-environment.d.ts} +0 -0
  86. /package/{flexible/index.d.ts → types/igo2-common-flexible.d.ts} +0 -0
  87. /package/{form/index.d.ts → types/igo2-common-form.d.ts} +0 -0
  88. /package/{home-button/index.d.ts → types/igo2-common-home-button.d.ts} +0 -0
  89. /package/{image/index.d.ts → types/igo2-common-image.d.ts} +0 -0
  90. /package/{interactive-tour/index.d.ts → types/igo2-common-interactive-tour.d.ts} +0 -0
  91. /package/{json-dialog/index.d.ts → types/igo2-common-json-dialog.d.ts} +0 -0
  92. /package/{keyvalue/index.d.ts → types/igo2-common-keyvalue.d.ts} +0 -0
  93. /package/{list/index.d.ts → types/igo2-common-list.d.ts} +0 -0
  94. /package/{panel/index.d.ts → types/igo2-common-panel.d.ts} +0 -0
  95. /package/{resizable-bar/index.d.ts → types/igo2-common-resizable-bar.d.ts} +0 -0
  96. /package/{select-value-dialog/index.d.ts → types/igo2-common-select-value-dialog.d.ts} +0 -0
  97. /package/{sidenav/index.d.ts → types/igo2-common-sidenav.d.ts} +0 -0
  98. /package/{spinner/index.d.ts → types/igo2-common-spinner.d.ts} +0 -0
  99. /package/{stop-propagation/index.d.ts → types/igo2-common-stop-propagation.d.ts} +0 -0
  100. /package/{table/index.d.ts → types/igo2-common-table.d.ts} +0 -0
  101. /package/{timepicker/index.d.ts → types/igo2-common-timepicker.d.ts} +0 -0
  102. /package/{tool/index.d.ts → types/igo2-common-tool.d.ts} +0 -0
  103. /package/{widget/index.d.ts → types/igo2-common-widget.d.ts} +0 -0
  104. /package/{workspace/index.d.ts → types/igo2-common-workspace.d.ts} +0 -0
  105. /package/{index.d.ts → types/igo2-common.d.ts} +0 -0
@@ -1,10 +1,9 @@
1
1
  import * as i0 from '@angular/core';
2
- import { input, output, HostListener, HostBinding, Directive, inject, ElementRef, Renderer2, effect, booleanAttribute, contentChildren, NgModule } from '@angular/core';
3
- import { SelectionModel } from '@angular/cdk/collections';
2
+ import { input, output, HostListener, HostBinding, Directive, inject, ElementRef, Renderer2, signal, effect, booleanAttribute, contentChildren, untracked, NgModule } from '@angular/core';
4
3
  import { MatTreeNode } from '@angular/material/tree';
5
4
 
6
5
  class DragAndDropDirective {
7
- allowedExtensions = input([], ...(ngDevMode ? [{ debugName: "allowedExtensions" }] : []));
6
+ allowedExtensions = input([], ...(ngDevMode ? [{ debugName: "allowedExtensions" }] : /* istanbul ignore next */ []));
8
7
  filesDropped = output();
9
8
  filesInvalid = output();
10
9
  background = 'inherit';
@@ -55,14 +54,13 @@ class DragAndDropDirective {
55
54
  }
56
55
  return filesObj;
57
56
  }
58
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: DragAndDropDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
59
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "20.3.16", type: DragAndDropDirective, isStandalone: true, selector: "[igoDragAndDrop]", inputs: { allowedExtensions: { classPropertyName: "allowedExtensions", publicName: "allowedExtensions", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { filesDropped: "filesDropped", filesInvalid: "filesInvalid" }, host: { listeners: { "dragover": "onDragOver($event)", "dragleave": "onDragLeave($event)", "drop": "onDrop($event)" }, properties: { "style.background": "this.background" } }, ngImport: i0 });
57
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.10", ngImport: i0, type: DragAndDropDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
58
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.10", type: DragAndDropDirective, isStandalone: true, selector: "[igoDragAndDrop]", inputs: { allowedExtensions: { classPropertyName: "allowedExtensions", publicName: "allowedExtensions", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { filesDropped: "filesDropped", filesInvalid: "filesInvalid" }, host: { listeners: { "dragover": "onDragOver($event)", "dragleave": "onDragLeave($event)", "drop": "onDrop($event)" }, properties: { "style.background": "this.background" } }, ngImport: i0 });
60
59
  }
61
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: DragAndDropDirective, decorators: [{
60
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.10", ngImport: i0, type: DragAndDropDirective, decorators: [{
62
61
  type: Directive,
63
62
  args: [{
64
- selector: '[igoDragAndDrop]',
65
- standalone: true
63
+ selector: '[igoDragAndDrop]'
66
64
  }]
67
65
  }], propDecorators: { allowedExtensions: [{ type: i0.Input, args: [{ isSignal: true, alias: "allowedExtensions", required: false }] }], filesDropped: [{ type: i0.Output, args: ["filesDropped"] }], filesInvalid: [{ type: i0.Output, args: ["filesInvalid"] }], background: [{
68
66
  type: HostBinding,
@@ -89,65 +87,110 @@ class TreeDragDropDirective {
89
87
  elementRef = inject(ElementRef);
90
88
  renderer = inject(Renderer2);
91
89
  draggedNode;
92
- dropNodeTarget;
90
+ dropNodeTarget = signal(null, ...(ngDevMode ? [{ debugName: "dropNodeTarget" }] : /* istanbul ignore next */ []));
93
91
  expandTimeout;
94
92
  nodesListeners;
95
93
  nodesEffect = effect(() => {
96
94
  this.nodes();
97
95
  this.addAllListener();
98
- }, ...(ngDevMode ? [{ debugName: "nodesEffect" }] : []));
99
- dropLineTarget;
100
- highlightedNode = new SelectionModel();
101
- treeControl = input.required(...(ngDevMode ? [{ debugName: "treeControl" }] : []));
96
+ }, ...(ngDevMode ? [{ debugName: "nodesEffect" }] : /* istanbul ignore next */ []));
97
+ dropLineTarget = signal(null, ...(ngDevMode ? [{ debugName: "dropLineTarget" }] : /* istanbul ignore next */ []));
98
+ previousDropLine = signal(null, ...(ngDevMode ? [{ debugName: "previousDropLine" }] : /* istanbul ignore next */ []));
99
+ dropPosition = signal(null, ...(ngDevMode ? [{ debugName: "dropPosition" }] : /* istanbul ignore next */ []));
100
+ dragging = signal(false, ...(ngDevMode ? [{ debugName: "dragging" }] : /* istanbul ignore next */ []));
101
+ // Use a Set or just manage classes manually since SelectionModel was providing simple toggle
102
+ // But we can stick to simple class logic
103
+ highlightedNode;
104
+ tree = input.required(...(ngDevMode ? [{ debugName: "tree" }] : /* istanbul ignore next */ []));
105
+ childrenAccessor = input.required(...(ngDevMode ? [{ debugName: "childrenAccessor" }] : /* istanbul ignore next */ []));
106
+ config = input.required(...(ngDevMode ? [{ debugName: "config" }] : /* istanbul ignore next */ []));
102
107
  /** The default is 5 */
103
- maxLevel = input(5, ...(ngDevMode ? [{ debugName: "maxLevel" }] : []));
104
- treeDragDropIsDisabled = input(false, ...(ngDevMode ? [{ debugName: "treeDragDropIsDisabled", transform: booleanAttribute }] : [{
105
- transform: booleanAttribute
106
- }]));
108
+ maxLevel = input(5, ...(ngDevMode ? [{ debugName: "maxLevel" }] : /* istanbul ignore next */ []));
109
+ treeDragDropIsDisabled = input(false, { ...(ngDevMode ? { debugName: "treeDragDropIsDisabled" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
107
110
  dragStart = output();
108
- // eslint-disable-next-line @angular-eslint/no-output-on-prefix
109
- onDrop = output();
110
- // eslint-disable-next-line @angular-eslint/no-output-on-prefix
111
- onDropError = output();
112
- hostDragOver(event) {
113
- event.preventDefault();
114
- }
115
- hostDrop(event) {
116
- this.drop(event);
117
- }
118
- dragging;
119
- nodes = contentChildren(MatTreeNode, ...(ngDevMode ? [{ debugName: "nodes", descendants: true }] : [{ descendants: true }]));
111
+ dropped = output();
112
+ droppedError = output();
113
+ nodes = contentChildren(MatTreeNode, { ...(ngDevMode ? { debugName: "nodes" } : /* istanbul ignore next */ {}), descendants: true });
120
114
  constructor() {
121
- this.onDrop.subscribe(() => this.dragEnd());
122
- this.highlightedNode.changed.subscribe((change) => {
123
- if (change.removed.length) {
124
- this.removeNodeClass(change.removed[0].id, '--drag-hover');
115
+ this.dropped.subscribe(() => this.dragEnd());
116
+ effect(() => {
117
+ const disabled = this.treeDragDropIsDisabled();
118
+ disabled ? this.removeAllListener() : this.addAllListener();
119
+ });
120
+ effect(() => {
121
+ const current = this.dropLineTarget();
122
+ const parent = this.elementRef.nativeElement.parentElement;
123
+ if (!current) {
124
+ untracked(() => {
125
+ const previous = this.previousDropLine();
126
+ if (previous !== null) {
127
+ this.renderer.removeChild(parent, previous);
128
+ this.previousDropLine.set(null);
129
+ }
130
+ });
125
131
  }
126
- if (change.added.length) {
127
- this.addNodeClass(change.added[0].id, '--drag-hover');
132
+ else {
133
+ this.renderer.appendChild(parent, current);
128
134
  }
129
135
  });
130
136
  effect(() => {
131
- const disabled = this.treeDragDropIsDisabled();
132
- disabled ? this.removeAllListener() : this.addAllListener();
137
+ if (!this.dragging()) {
138
+ return;
139
+ }
140
+ const targetNode = this.dropNodeTarget();
141
+ const position = this.dropPosition();
142
+ const dropLineTarget = this.dropLineTarget();
143
+ if (targetNode) {
144
+ this.setHighlightedNode(targetNode);
145
+ if (position) {
146
+ if (dropLineTarget) {
147
+ this.updateDropTargetLinePosition(position, dropLineTarget);
148
+ }
149
+ this.handleGroupExpansion(targetNode, position.type === 'inside');
150
+ }
151
+ }
133
152
  });
134
153
  }
154
+ get isGroup() {
155
+ return this.config().isGroup;
156
+ }
157
+ get getDescendantLevels() {
158
+ return this.config().descendantLevels;
159
+ }
135
160
  ngOnDestroy() {
136
161
  this.removeAllListener();
162
+ this.removeDropTargetLine();
137
163
  if (this.nodesEffect) {
138
- // EffectRef provides destroy() to stop the effect
139
164
  this.nodesEffect.destroy();
140
165
  this.nodesEffect = undefined;
141
166
  }
142
167
  }
168
+ hostDragOver(event) {
169
+ event.preventDefault();
170
+ }
171
+ hostDragLeave(event) {
172
+ const rect = this.elementRef.nativeElement.getBoundingClientRect();
173
+ if (event.clientY < rect.top ||
174
+ event.clientY >= rect.bottom ||
175
+ event.clientX < rect.left ||
176
+ event.clientX >= rect.right) {
177
+ this.dragLeave();
178
+ }
179
+ }
180
+ hostDrop(event) {
181
+ this.drop(event);
182
+ }
143
183
  onDragStart(node) {
144
- this.dragging = true;
184
+ this.addDropTargetLine();
185
+ this.dragging.set(true);
145
186
  this.draggedNode = node;
146
187
  this.addNodeClass(node.id, '--dragged');
147
188
  this.dragStart.emit(node);
148
189
  }
149
190
  dragEnd() {
150
- this.dragging = false;
191
+ this.dragging.set(false);
192
+ this.dropNodeTarget.set(null);
193
+ this.dropPosition.set(null);
151
194
  if (this.draggedNode) {
152
195
  this.removeNodeClass(this.draggedNode.id, '--dragged');
153
196
  this.draggedNode = null;
@@ -158,71 +201,81 @@ class TreeDragDropDirective {
158
201
  dragOver(node, event) {
159
202
  event.preventDefault();
160
203
  event.stopPropagation();
161
- this.dropNodeTarget = node;
204
+ this.dropNodeTarget.set(node);
162
205
  const position = this.getPosition(event, node);
163
- this.updateDropTargetLinePosition(position);
164
- this.setHighlightedNode(node);
165
- this.handleGroupExpansion(node, position.type === 'inside');
206
+ this.dropPosition.set(position);
166
207
  }
167
208
  dragLeave() {
168
209
  clearTimeout(this.expandTimeout);
169
210
  this.expandTimeout = null;
170
- this.highlightedNode.clear();
211
+ if (this.highlightedNode) {
212
+ this.removeNodeClass(this.highlightedNode.id, '--drag-hover');
213
+ this.highlightedNode = undefined;
214
+ }
171
215
  }
172
216
  drop(event) {
173
- if (!this.dropNodeTarget || this.treeDragDropIsDisabled()) {
217
+ let nodeTarget = this.dropNodeTarget();
218
+ if (!nodeTarget || this.treeDragDropIsDisabled()) {
174
219
  return;
175
220
  }
176
- const dropPosition = this.getPosition(event, this.dropNodeTarget);
177
- const validation = this.canDropNode(this.dropNodeTarget, dropPosition);
221
+ const dropPosition = this.getPosition(event, nodeTarget);
222
+ const validation = this.canDropNode(nodeTarget, dropPosition);
178
223
  if (!validation.canDrop) {
179
- this.onDropError.emit(validation);
224
+ this.droppedError.emit(validation);
180
225
  return;
181
226
  }
227
+ let targetNodeLevel = this.getNodeLevel(nodeTarget);
182
228
  // Allow to drop a last child outside is group. We refer to it's ancestor for the target
183
229
  if (dropPosition.type === 'below' &&
184
- dropPosition.level !== this.dropNodeTarget.level) {
185
- this.dropNodeTarget = this.getNodeAncestors(this.dropNodeTarget.id, dropPosition.level);
230
+ dropPosition.level !== targetNodeLevel) {
231
+ const ancestor = this.getNodeAncestors(nodeTarget.id, dropPosition.level);
232
+ this.dropNodeTarget.set(ancestor);
233
+ nodeTarget = ancestor;
234
+ targetNodeLevel = this.getNodeLevel(nodeTarget);
186
235
  }
187
- if (this.dropNodeTarget.isGroup) {
236
+ if (this.isGroup(nodeTarget)) {
188
237
  if (dropPosition.type === 'inside') {
189
- const isExpanded = this.treeControl().isExpanded(this.dropNodeTarget);
238
+ const isExpanded = this.tree().isExpanded(nodeTarget);
190
239
  if (isExpanded) {
191
- const children = this.getDirectDescendants(this.dropNodeTarget);
240
+ const children = this.getDirectDescendants(nodeTarget);
192
241
  if (children[0]?.id === this.draggedNode.id) {
193
242
  return;
194
243
  }
195
244
  }
196
- this.treeControl().expand(this.dropNodeTarget);
197
- return this.onDrop.emit({
245
+ this.tree().expand(nodeTarget);
246
+ return this.dropped.emit({
198
247
  node: this.draggedNode,
199
- ref: this.dropNodeTarget,
248
+ ref: nodeTarget,
200
249
  position: dropPosition.type
201
250
  });
202
251
  }
203
252
  }
204
253
  if (dropPosition.type === 'below' &&
205
- dropPosition.level !== this.dropNodeTarget.level) {
206
- const ancestor = this.getNodeAncestors(this.dropNodeTarget.id);
207
- return this.onDrop.emit({
254
+ dropPosition.level !== targetNodeLevel) {
255
+ const ancestor = this.getNodeAncestors(nodeTarget.id);
256
+ return this.dropped.emit({
208
257
  node: this.draggedNode,
209
258
  ref: ancestor,
210
259
  position: dropPosition.type
211
260
  });
212
261
  }
213
- this.onDrop.emit({
262
+ this.dropped.emit({
214
263
  node: this.draggedNode,
215
- ref: this.dropNodeTarget,
264
+ ref: nodeTarget,
216
265
  position: dropPosition.type
217
266
  });
218
267
  }
219
268
  addNodeClass(id, className) {
220
- const node = this.nodes().find((node) => node.data.id === id);
221
- this.renderer.addClass(node['_elementRef'].nativeElement, className);
269
+ const node = this.findTreeNode(id);
270
+ if (node) {
271
+ this.renderer.addClass(node['_elementRef'].nativeElement, className);
272
+ }
222
273
  }
223
274
  removeNodeClass(id, className) {
224
- const node = this.nodes().find((node) => node.data.id === id);
225
- this.renderer.removeClass(node['_elementRef'].nativeElement, className);
275
+ const node = this.findTreeNode(id);
276
+ if (node) {
277
+ this.renderer.removeClass(node['_elementRef'].nativeElement, className);
278
+ }
226
279
  }
227
280
  addAllListener() {
228
281
  if (this.treeDragDropIsDisabled()) {
@@ -256,52 +309,70 @@ class TreeDragDropDirective {
256
309
  this.nodesListeners = null;
257
310
  }
258
311
  setHighlightedNode(node) {
259
- const toHighlight = node.isGroup ? node : this.getNodeAncestors(node.id);
260
- toHighlight
261
- ? this.highlightedNode.select(toHighlight)
262
- : this.highlightedNode.clear();
312
+ const toHighlight = this.isGroup(node)
313
+ ? node
314
+ : this.getNodeAncestors(node.id);
315
+ if (this.highlightedNode && this.highlightedNode.id !== toHighlight?.id) {
316
+ this.removeNodeClass(this.highlightedNode.id, '--drag-hover');
317
+ this.highlightedNode = undefined;
318
+ }
319
+ if (toHighlight) {
320
+ this.highlightedNode = toHighlight;
321
+ this.addNodeClass(toHighlight.id, '--drag-hover');
322
+ }
323
+ else if (this.highlightedNode) {
324
+ this.removeNodeClass(this.highlightedNode.id, '--drag-hover');
325
+ this.highlightedNode = undefined;
326
+ }
263
327
  }
264
328
  addDropTargetLine() {
265
329
  const target = this.renderer.createElement('div');
266
330
  target.classList.add('drop-target-line');
267
331
  target.setAttribute('style', `position: absolute; top: 0; width: 100%; pointer-events: none; z-index: 4; height: 2px; background-color: black; transition: margin-left 150ms;`);
268
- this.dropLineTarget = target;
269
- this.renderer.appendChild(this.elementRef.nativeElement.parentElement, this.dropLineTarget);
332
+ this.dropLineTarget.set(target);
270
333
  }
271
334
  removeDropTargetLine() {
272
- if (!this.dropLineTarget) {
273
- return;
335
+ const target = this.dropLineTarget();
336
+ if (target) {
337
+ this.previousDropLine.set(target);
338
+ this.dropLineTarget.set(null);
274
339
  }
275
- this.renderer.removeChild(this.elementRef.nativeElement.parentElement, this.dropLineTarget);
276
- this.dropLineTarget = null;
277
340
  }
278
- updateDropTargetLinePosition(position) {
279
- if (!this.dropLineTarget) {
280
- this.addDropTargetLine();
281
- }
341
+ hideDropTargetLine() {
342
+ const target = this.dropLineTarget();
343
+ this.renderer.setStyle(target, 'display', 'none');
344
+ }
345
+ showDropTargetLine() {
346
+ const target = this.dropLineTarget();
347
+ this.renderer.setStyle(target, 'display', 'block');
348
+ }
349
+ updateDropTargetLinePosition(position, dropLineTarget) {
282
350
  if (position.type === 'inside') {
283
- return this.removeDropTargetLine();
351
+ return this.hideDropTargetLine();
352
+ }
353
+ else {
354
+ this.showDropTargetLine();
284
355
  }
285
- this.renderer.setStyle(this.dropLineTarget, 'margin-left', position.level * 24 + 20 + 'px');
286
- this.renderer.setStyle(this.dropLineTarget, 'transform', 'translate3d(0,' + position.y + 'px, 0)');
356
+ this.renderer.setStyle(dropLineTarget, 'margin-left', position.level * 24 + 20 + 'px');
357
+ this.renderer.setStyle(dropLineTarget, 'transform', 'translate3d(0,' + position.y + 'px, 0)');
287
358
  }
288
359
  handleGroupExpansion(node, isInside) {
289
360
  if (!isInside) {
290
361
  return this.dragLeave();
291
362
  }
292
- const isOpen = this.treeControl().isExpanded(node);
363
+ const isOpen = this.tree().isExpanded(node);
293
364
  if (!isOpen && !this.expandTimeout) {
294
365
  this.expandTimeout = window.setTimeout(() => {
295
- this.treeControl().expand(node);
366
+ this.tree().expand(node);
296
367
  }, 1200);
297
368
  }
298
369
  }
299
370
  getNodeElement(node) {
300
- const treeNode = this.nodes().find((n) => n.data.id === node.id);
371
+ const treeNode = this.findTreeNode(node.id);
301
372
  return treeNode?.['_elementRef'].nativeElement;
302
373
  }
303
374
  canDropNode(hoveredNode, position) {
304
- if (this.draggedNode.isGroup) {
375
+ if (this.isGroup(this.draggedNode)) {
305
376
  return this.canDropGroup(hoveredNode, position);
306
377
  }
307
378
  const hasMaxLevelRestrictions = this.validateMaxHierarchyLevel(position);
@@ -318,14 +389,20 @@ class TreeDragDropDirective {
318
389
  message: 'igo.common.dragDrop.cannot.dropInsideItself'
319
390
  };
320
391
  }
392
+ const isHoverDescendant = this.isHoverDescendant(hoveredNode.id, hoveredNode);
393
+ if (isHoverDescendant) {
394
+ return {
395
+ canDrop: !isHoverDescendant,
396
+ message: 'igo.common.dragDrop.cannot.dropInsideItself'
397
+ };
398
+ }
321
399
  const hasMaxLevelRestrictions = this.validateMaxHierarchyLevel(position);
322
400
  if (hasMaxLevelRestrictions) {
323
401
  return hasMaxLevelRestrictions;
324
402
  }
325
- const isHoverDescendant = this.isHoverDescendant(hoveredNode.id);
326
403
  return {
327
- canDrop: !isHoverDescendant,
328
- message: isHoverDescendant && 'igo.common.dragDrop.cannot.dropInsideItself'
404
+ canDrop: true,
405
+ message: undefined
329
406
  };
330
407
  }
331
408
  validateMaxHierarchyLevel(position) {
@@ -334,9 +411,9 @@ class TreeDragDropDirective {
334
411
  return;
335
412
  }
336
413
  let level = position.type === 'inside' ? position.level + 1 : position.level;
337
- if (this.draggedNode.isGroup) {
414
+ if (this.isGroup(this.draggedNode)) {
338
415
  // We add an extra level +1 to avoid empty group in group
339
- level = level + (this.draggedNode.descendantLevels ?? 0) + 1;
416
+ level = level + +(this.getDescendantLevels(this.draggedNode) ?? 0) + 1;
340
417
  }
341
418
  if (level > maxLevel) {
342
419
  return {
@@ -346,21 +423,27 @@ class TreeDragDropDirective {
346
423
  };
347
424
  }
348
425
  }
349
- isHoverDescendant(id) {
350
- return this.treeControl()
351
- .getDescendants(this.draggedNode)
352
- .some((child) => child.id === id);
426
+ getDescendants(node) {
427
+ const children = this.childrenAccessor()(node) ?? [];
428
+ const descendants = [...children];
429
+ children.forEach((child) => {
430
+ descendants.push(...this.getDescendants(child));
431
+ });
432
+ return descendants;
433
+ }
434
+ isHoverDescendant(id, _hoveredNode) {
435
+ return this.getDescendants(this.draggedNode).some((child) => child.id === id);
353
436
  }
354
437
  getPosition(event, hoveredNode) {
355
- if (this.draggedNode.isGroup) {
356
- if (this.isHoverDescendant(hoveredNode.id)) {
438
+ if (this.isGroup(this.draggedNode)) {
439
+ if (this.isHoverDescendant(hoveredNode.id, hoveredNode)) {
357
440
  hoveredNode = this.draggedNode;
358
441
  }
359
442
  }
360
443
  let positionType = this.getPositionType(event, hoveredNode);
361
- const bellowOpenedGroup = hoveredNode.isGroup &&
444
+ const bellowOpenedGroup = this.isGroup(hoveredNode) &&
362
445
  positionType === 'below' &&
363
- this.treeControl().isExpanded(hoveredNode);
446
+ this.tree().isExpanded(hoveredNode);
364
447
  if (bellowOpenedGroup) {
365
448
  positionType = 'inside';
366
449
  }
@@ -384,7 +467,7 @@ class TreeDragDropDirective {
384
467
  const middle = rect.top + rect.height / 2;
385
468
  const y = event.y;
386
469
  const selfReferencing = this.draggedNode.id === hoveredNode.id;
387
- if (hoveredNode.isGroup && !selfReferencing) {
470
+ if (this.isGroup(hoveredNode) && !selfReferencing) {
388
471
  const tolerence = 5;
389
472
  if (y <= middle + tolerence && y >= middle - tolerence) {
390
473
  return 'inside';
@@ -394,63 +477,92 @@ class TreeDragDropDirective {
394
477
  return isBelow ? 'below' : 'above';
395
478
  }
396
479
  getPositionLevel(hoveredNode, type, x) {
397
- if (hoveredNode.level === 0) {
480
+ const hoveredNodeLevel = this.getNodeLevel(hoveredNode);
481
+ if (hoveredNodeLevel === 0) {
398
482
  return 0;
399
483
  }
400
484
  const ancestor = this.getNodeAncestors(hoveredNode.id);
485
+ if (!ancestor)
486
+ return hoveredNodeLevel;
401
487
  const children = this.getDirectDescendants(ancestor);
402
488
  const lastChild = [...children].pop();
403
- if (type === 'below' && lastChild.id === hoveredNode.id) {
489
+ if (type === 'below' && lastChild?.id === hoveredNode.id) {
404
490
  const target = this.getNodeElement(hoveredNode);
405
491
  const rect = target.getBoundingClientRect();
406
492
  const indentation = 24;
407
493
  const xMin = rect.x + indentation;
408
- const xMax = xMin + indentation * hoveredNode.level;
494
+ const xMax = xMin + indentation * hoveredNodeLevel;
409
495
  const isInsideSameGroup = x > xMax;
410
496
  if (!isInsideSameGroup) {
411
497
  const levelSubstracted = Math.round((xMax - x) / indentation);
412
- return Math.max(0, hoveredNode.level - levelSubstracted);
498
+ return Math.max(0, hoveredNodeLevel - levelSubstracted);
413
499
  }
414
500
  }
415
- return hoveredNode.level;
501
+ return hoveredNodeLevel;
416
502
  }
417
503
  /**
418
504
  * @param level if level is defined with go to the defined levle to find ancestor. Sinon on prend le current ancestor
419
505
  */
420
506
  getNodeAncestors(id, level) {
421
- const nodes = this.treeControl().dataNodes;
422
- const index = nodes.findIndex((node) => node.id === id);
423
- const targetLevel = level ?? Math.max(0, nodes[index].level - 1);
424
- return nodes
425
- .slice(0, index)
426
- .reverse()
427
- .find((node) => node.level === targetLevel);
507
+ const path = this.getAncestorsPath(id);
508
+ if (path.length === 0) {
509
+ return undefined;
510
+ }
511
+ if (level !== undefined) {
512
+ return path[level];
513
+ }
514
+ return path[path.length - 1];
515
+ }
516
+ getAncestorsPath(id) {
517
+ const nodes = this.nodes();
518
+ const roots = nodes.filter((n) => n.level === 0).map((n) => n.data);
519
+ for (const root of roots) {
520
+ const path = [];
521
+ if (this.findPath(root, id, path)) {
522
+ return path;
523
+ }
524
+ }
525
+ return [];
526
+ }
527
+ findPath(currentNode, targetId, path) {
528
+ if (String(currentNode.id) === String(targetId)) {
529
+ return true;
530
+ }
531
+ const children = this.childrenAccessor()(currentNode) ?? [];
532
+ for (const child of children) {
533
+ path.push(currentNode);
534
+ if (this.findPath(child, targetId, path)) {
535
+ return true;
536
+ }
537
+ path.pop();
538
+ }
539
+ return false;
540
+ }
541
+ getNodeLevel(node) {
542
+ const treeNode = this.findTreeNode(node.id);
543
+ return treeNode ? treeNode.level : 0;
428
544
  }
429
545
  getDirectDescendants(node) {
430
- const level = node.level + 1;
431
- return this.treeControl()
432
- .getDescendants(node)
433
- .filter((child) => child.level === level);
546
+ return this.childrenAccessor()(node) ?? [];
547
+ }
548
+ findTreeNode(id) {
549
+ return this.nodes().find((n) => String(n.data.id) === String(id));
434
550
  }
435
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: TreeDragDropDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
436
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.2.0", version: "20.3.16", type: TreeDragDropDirective, isStandalone: true, selector: "[igoTreeDragDrop]", inputs: { treeControl: { classPropertyName: "treeControl", publicName: "treeControl", isSignal: true, isRequired: true, transformFunction: null }, maxLevel: { classPropertyName: "maxLevel", publicName: "maxLevel", isSignal: true, isRequired: false, transformFunction: null }, treeDragDropIsDisabled: { classPropertyName: "treeDragDropIsDisabled", publicName: "treeDragDropIsDisabled", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { dragStart: "dragStart", onDrop: "onDrop", onDropError: "onDropError" }, host: { listeners: { "dragover": "hostDragOver($event)", "drop": "hostDrop($event)" }, properties: { "class.--dragging": "this.dragging" } }, queries: [{ propertyName: "nodes", predicate: MatTreeNode, descendants: true, isSignal: true }], ngImport: i0 });
551
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.10", ngImport: i0, type: TreeDragDropDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
552
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.2.0", version: "21.2.10", type: TreeDragDropDirective, isStandalone: true, selector: "[igoTreeDragDrop]", inputs: { tree: { classPropertyName: "tree", publicName: "tree", isSignal: true, isRequired: true, transformFunction: null }, childrenAccessor: { classPropertyName: "childrenAccessor", publicName: "childrenAccessor", isSignal: true, isRequired: true, transformFunction: null }, config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: true, transformFunction: null }, maxLevel: { classPropertyName: "maxLevel", publicName: "maxLevel", isSignal: true, isRequired: false, transformFunction: null }, treeDragDropIsDisabled: { classPropertyName: "treeDragDropIsDisabled", publicName: "treeDragDropIsDisabled", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { dragStart: "dragStart", dropped: "dropped", droppedError: "droppedError" }, host: { listeners: { "dragover": "hostDragOver($event)", "dragleave": "hostDragLeave($event)", "drop": "hostDrop($event)" }, properties: { "class.--dragging": "dragging()" } }, queries: [{ propertyName: "nodes", predicate: MatTreeNode, descendants: true, isSignal: true }], ngImport: i0 });
437
553
  }
438
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: TreeDragDropDirective, decorators: [{
554
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.10", ngImport: i0, type: TreeDragDropDirective, decorators: [{
439
555
  type: Directive,
440
556
  args: [{
441
557
  selector: '[igoTreeDragDrop]',
442
- standalone: true
558
+ host: {
559
+ '[class.--dragging]': 'dragging()',
560
+ '(dragover)': 'hostDragOver($event)',
561
+ '(dragleave)': 'hostDragLeave($event)',
562
+ '(drop)': 'hostDrop($event)'
563
+ }
443
564
  }]
444
- }], ctorParameters: () => [], propDecorators: { treeControl: [{ type: i0.Input, args: [{ isSignal: true, alias: "treeControl", required: true }] }], maxLevel: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxLevel", required: false }] }], treeDragDropIsDisabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "treeDragDropIsDisabled", required: false }] }], dragStart: [{ type: i0.Output, args: ["dragStart"] }], onDrop: [{ type: i0.Output, args: ["onDrop"] }], onDropError: [{ type: i0.Output, args: ["onDropError"] }], hostDragOver: [{
445
- type: HostListener,
446
- args: ['dragover', ['$event']]
447
- }], hostDrop: [{
448
- type: HostListener,
449
- args: ['drop', ['$event']]
450
- }], dragging: [{
451
- type: HostBinding,
452
- args: ['class.--dragging']
453
- }], nodes: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => MatTreeNode), { ...{ descendants: true }, isSignal: true }] }] } });
565
+ }], ctorParameters: () => [], propDecorators: { tree: [{ type: i0.Input, args: [{ isSignal: true, alias: "tree", required: true }] }], childrenAccessor: [{ type: i0.Input, args: [{ isSignal: true, alias: "childrenAccessor", required: true }] }], config: [{ type: i0.Input, args: [{ isSignal: true, alias: "config", required: true }] }], maxLevel: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxLevel", required: false }] }], treeDragDropIsDisabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "treeDragDropIsDisabled", required: false }] }], dragStart: [{ type: i0.Output, args: ["dragStart"] }], dropped: [{ type: i0.Output, args: ["dropped"] }], droppedError: [{ type: i0.Output, args: ["droppedError"] }], nodes: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => MatTreeNode), { ...{ descendants: true }, isSignal: true }] }] } });
454
566
 
455
567
  /**
456
568
  * @deprecated import the DragAndDropDirective directly
@@ -462,11 +574,11 @@ class IgoDrapDropModule {
462
574
  providers: []
463
575
  };
464
576
  }
465
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: IgoDrapDropModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
466
- static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.3.16", ngImport: i0, type: IgoDrapDropModule, imports: [DragAndDropDirective, TreeDragDropDirective], exports: [DragAndDropDirective, TreeDragDropDirective] });
467
- static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: IgoDrapDropModule });
577
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.10", ngImport: i0, type: IgoDrapDropModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
578
+ static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "21.2.10", ngImport: i0, type: IgoDrapDropModule, imports: [DragAndDropDirective, TreeDragDropDirective], exports: [DragAndDropDirective, TreeDragDropDirective] });
579
+ static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "21.2.10", ngImport: i0, type: IgoDrapDropModule });
468
580
  }
469
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: IgoDrapDropModule, decorators: [{
581
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.10", ngImport: i0, type: IgoDrapDropModule, decorators: [{
470
582
  type: NgModule,
471
583
  args: [{
472
584
  imports: [DragAndDropDirective, TreeDragDropDirective],