1
1
import { dndState } from '$lib/stores/dnd.svelte.js' ;
2
2
import type { DragDropOptions , DragDropState } from '$lib/types/index.js' ;
3
3
4
+ const DEFAULT_DRAG_OVER_CLASS = 'drag-over' ;
5
+
4
6
export function droppable < T > ( node : HTMLElement , options : DragDropOptions < T > ) {
7
+ const dragOverClass = ( options . attributes ?. draggingClass || DEFAULT_DRAG_OVER_CLASS ) . split ( ' ' ) ;
8
+
5
9
function handleDragEnter ( event : DragEvent ) {
6
10
if ( options . disabled ) return ;
7
11
event . preventDefault ( ) ;
8
12
13
+ const target = event . target as HTMLElement ;
14
+
9
15
dndState . targetContainer = options . container ;
10
- node . classList . add ( 'drag-over' ) ;
16
+ dndState . targetElement = target ;
17
+
18
+ node . classList . add ( ...dragOverClass ) ;
11
19
options . callbacks ?. onDragEnter ?.( dndState as DragDropState < T > ) ;
12
20
}
13
21
14
22
function handleDragLeave ( event : DragEvent ) {
15
23
if ( options . disabled ) return ;
16
24
17
25
const target = event . target as HTMLElement ;
18
- if ( ! node . contains ( target ) ) {
19
- dndState . targetContainer = null ;
20
- node . classList . remove ( 'drag-over' ) ;
21
- options . callbacks ?. onDragLeave ?.( dndState as DragDropState < T > ) ;
22
- }
26
+
27
+ // check if element is still being dragged over
28
+ if ( ! dndState . targetElement ?. isSameNode ( target ) ) return ;
29
+
30
+ node . classList . remove ( ...dragOverClass ) ;
31
+
32
+ options . callbacks ?. onDragLeave ?.( dndState as DragDropState < T > ) ;
33
+
34
+ dndState . targetContainer = null ;
35
+ dndState . targetElement = null ;
23
36
}
24
37
25
38
function handleDragOver ( event : DragEvent ) {
@@ -37,7 +50,7 @@ export function droppable<T>(node: HTMLElement, options: DragDropOptions<T>) {
37
50
if ( options . disabled ) return ;
38
51
event . preventDefault ( ) ;
39
52
40
- node . classList . remove ( 'drag-over' ) ;
53
+ node . classList . remove ( ... dragOverClass ) ;
41
54
42
55
try {
43
56
if ( event . dataTransfer ) {
@@ -55,22 +68,22 @@ export function droppable<T>(node: HTMLElement, options: DragDropOptions<T>) {
55
68
if ( options . disabled || ! dndState . isDragging ) return ;
56
69
57
70
dndState . targetContainer = options . container ;
58
- node . classList . add ( 'drag-over' ) ;
71
+ node . classList . add ( ... dragOverClass ) ;
59
72
options . callbacks ?. onDragEnter ?.( dndState as DragDropState < T > ) ;
60
73
}
61
74
62
75
function handlePointerOut ( event : PointerEvent ) {
63
76
if ( options . disabled || ! dndState . isDragging ) return ;
64
77
65
78
dndState . targetContainer = null ;
66
- node . classList . remove ( 'drag-over' ) ;
79
+ node . classList . remove ( ... dragOverClass ) ;
67
80
options . callbacks ?. onDragLeave ?.( dndState as DragDropState < T > ) ;
68
81
}
69
82
70
83
function handlePointerUp ( event : PointerEvent ) {
71
84
if ( options . disabled || ! dndState . isDragging ) return ;
72
85
73
- node . classList . remove ( 'drag-over' ) ;
86
+ node . classList . remove ( ... dragOverClass ) ;
74
87
options . callbacks ?. onDrop ?.( dndState as DragDropState < T > ) ;
75
88
}
76
89
0 commit comments