@@ -3,11 +3,9 @@ import customElement from "@ui5/webcomponents-base/dist/decorators/customElement
3
3
import property from "@ui5/webcomponents-base/dist/decorators/property.js" ;
4
4
import slot from "@ui5/webcomponents-base/dist/decorators/slot.js" ;
5
5
import DragRegistry from "@ui5/webcomponents-base/dist/util/dragAndDrop/DragRegistry.js" ;
6
- import handleDragOver from "@ui5/webcomponents-base/dist/util/dragAndDrop/handleDragOver.js" ;
7
- import handleDrop from "@ui5/webcomponents-base/dist/util/dragAndDrop/handleDrop.js" ;
8
- import { findClosestPosition } from "@ui5/webcomponents-base/dist/util/dragAndDrop/findClosestPosition.js" ;
6
+ import createDragAndDropMixin from "@ui5/webcomponents-base/dist/util/dragAndDrop/DragAndDropMixin.js" ;
9
7
import Orientation from "@ui5/webcomponents-base/dist/types/Orientation.js" ;
10
- import MovePlacement from "@ui5/webcomponents-base/dist/types/MovePlacement.js" ;
8
+ import type MovePlacement from "@ui5/webcomponents-base/dist/types/MovePlacement.js" ;
11
9
import event from "@ui5/webcomponents-base/dist/decorators/event-strict.js" ;
12
10
import jsxRenderer from "@ui5/webcomponents-base/dist/renderer/JsxRenderer.js" ;
13
11
import type DropIndicator from "./DropIndicator.js" ;
@@ -221,6 +219,13 @@ class Tree extends UI5Element {
221
219
"move" : TreeMoveEventDetail ,
222
220
"move-over" : TreeMoveEventDetail ,
223
221
}
222
+
223
+ _ondragenter ! : ( e : DragEvent ) => void ;
224
+ _ondragleave ! : ( e : DragEvent ) => void ;
225
+ _ondragover ! : ( e : DragEvent ) => void ;
226
+ _ondrop ! : ( e : DragEvent ) => void ;
227
+ _cleanupDragAndDrop ! : ( ) => void ;
228
+
224
229
/**
225
230
* Defines the selection mode of the component. Since the tree uses a `ui5-list` to display its structure,
226
231
* the tree modes are exactly the same as the list modes, and are all applicable.
@@ -311,12 +316,63 @@ class Tree extends UI5Element {
311
316
@slot ( )
312
317
header ! : Array < HTMLElement > ;
313
318
319
+ constructor ( ) {
320
+ super ( ) ;
321
+
322
+ const dragDropMixin = createDragAndDropMixin ( {
323
+ getItemsForDragDrop : ( ) => {
324
+ const allLiNodesTraversed : Array < HTMLElement > = [ ] ;
325
+ this . walk ( item => {
326
+ const liElement = item . shadowRoot ?. querySelector ( "li" ) ;
327
+ if ( liElement ) {
328
+ allLiNodesTraversed . push ( liElement ) ;
329
+ }
330
+ } ) ;
331
+ return allLiNodesTraversed ;
332
+ } ,
333
+ getOrientation : ( ) => Orientation . Vertical ,
334
+ getDropIndicator : ( ) => ( this . dropIndicatorDOM ? {
335
+ targetReference : this . dropIndicatorDOM . targetReference ,
336
+ placement : this . dropIndicatorDOM . placement ,
337
+ } : null ) ,
338
+ setDropIndicator : ( targetReference : HTMLElement | null , placement ?: any ) => {
339
+ if ( this . dropIndicatorDOM ) {
340
+ this . dropIndicatorDOM . targetReference = targetReference ;
341
+ if ( placement !== undefined ) {
342
+ this . dropIndicatorDOM . placement = placement ;
343
+ }
344
+ }
345
+ } ,
346
+ getTargetFromPosition : ( element : HTMLElement ) => {
347
+ const rootNode = element . getRootNode ( ) ;
348
+ if ( rootNode instanceof ShadowRoot && rootNode . host instanceof HTMLElement ) {
349
+ return rootNode . host ;
350
+ }
351
+ return element ; // Fallback to original element
352
+ } ,
353
+ shouldContainsDraggedElement : ( draggedElement : HTMLElement , targetElement : HTMLElement ) => {
354
+ return draggedElement . contains ( targetElement ) ;
355
+ } ,
356
+ } ) ;
357
+
358
+ this . _ondragenter = dragDropMixin . _ondragenter . bind ( this ) ;
359
+ this . _ondragleave = dragDropMixin . _ondragleave . bind ( this ) ;
360
+ this . _ondragover = dragDropMixin . _ondragover . bind ( this ) ;
361
+ this . _ondrop = dragDropMixin . _ondrop . bind ( this ) ;
362
+ this . _cleanupDragAndDrop = dragDropMixin . _cleanupDragAndDrop ;
363
+ }
364
+
314
365
onEnterDOM ( ) {
315
366
DragRegistry . subscribe ( this ) ;
316
367
}
317
368
318
369
onExitDOM ( ) {
319
370
DragRegistry . unsubscribe ( this ) ;
371
+
372
+ // Clean up drag and drop mixin to prevent memory leaks
373
+ if ( this . _cleanupDragAndDrop ) {
374
+ this . _cleanupDragAndDrop ( ) ;
375
+ }
320
376
}
321
377
322
378
onBeforeRendering ( ) {
@@ -345,59 +401,6 @@ class Tree extends UI5Element {
345
401
return ! ! this . header . length ;
346
402
}
347
403
348
- _ondragenter ( e : DragEvent ) {
349
- e . preventDefault ( ) ;
350
- }
351
-
352
- _ondragleave ( e : DragEvent ) {
353
- if ( e . relatedTarget instanceof Node && this . shadowRoot ! . contains ( e . relatedTarget ) ) {
354
- return ;
355
- }
356
-
357
- this . dropIndicatorDOM ! . targetReference = null ;
358
- }
359
-
360
- _ondragover ( e : DragEvent ) {
361
- const draggedElement = DragRegistry . getDraggedElement ( ) ;
362
- const allLiNodesTraversed : Array < HTMLElement > = [ ] ; // use the only <li> nodes to determine positioning
363
- if ( ! ( e . target instanceof HTMLElement ) || ! draggedElement ) {
364
- return ;
365
- }
366
-
367
- this . walk ( item => {
368
- allLiNodesTraversed . push ( item . shadowRoot ! . querySelector ( "li" ) ! ) ;
369
- } ) ;
370
-
371
- const closestPosition = findClosestPosition (
372
- allLiNodesTraversed ,
373
- e . clientY ,
374
- Orientation . Vertical ,
375
- ) ;
376
-
377
- if ( ! closestPosition ) {
378
- this . dropIndicatorDOM ! . targetReference = null ;
379
- return ;
380
- }
381
-
382
- closestPosition . element = < HTMLElement > ( < ShadowRoot > closestPosition . element . getRootNode ( ) ) . host ;
383
- if ( draggedElement . contains ( closestPosition . element ) ) { return ; }
384
- if ( closestPosition . element === draggedElement ) {
385
- closestPosition . placements = closestPosition . placements . filter ( placement => placement !== MovePlacement . On ) ;
386
- }
387
-
388
- const { targetReference, placement } = handleDragOver ( e , this , closestPosition , closestPosition . element ) ;
389
- this . dropIndicatorDOM ! . targetReference = targetReference ;
390
- this . dropIndicatorDOM ! . placement = placement ;
391
- }
392
-
393
- _ondrop ( e : DragEvent ) {
394
- if ( ! this . dropIndicatorDOM ?. targetReference || ! this . dropIndicatorDOM ?. placement ) {
395
- return ;
396
- }
397
- handleDrop ( e , this , this . dropIndicatorDOM . targetReference , this . dropIndicatorDOM . placement ) ;
398
- this . dropIndicatorDOM . targetReference = null ;
399
- }
400
-
401
404
_onListItemStepIn ( e : CustomEvent < TreeItemBaseStepInEventDetail > ) {
402
405
const treeItem = e . detail . item ;
403
406
if ( treeItem . items . length > 0 ) {
0 commit comments