@@ -49,18 +49,20 @@ onMounted(() => {
49
49
const emit = defineEmits ([" update:list" , " start" , " end" , " update" ]);
50
50
51
51
const hasHandleAtPosition = (event : MouseEvent | DragEvent ) => {
52
- const { x, y } = event ;
52
+ let { clientX : x, clientY : y } = event ;
53
53
const elementsAtPosition = document .elementsFromPoint (x , y );
54
54
return elementsAtPosition .reduce <boolean | null >(
55
55
(clickedHandle , elementAtPosition ) => {
56
56
// If we already have a boolean result, return that
57
- if (typeof clickedHandle === " boolean" ) return clickedHandle ;
57
+ if (typeof clickedHandle === " boolean" )
58
+ return clickedHandle ;
58
59
// If the clicked element (or one of its parents) has the handle class, we clicked the handle
59
60
if (elementAtPosition .classList .contains (props .handleClass ! ))
60
61
return true ;
61
62
// If we've reached the draggable element itself, we found no handle, so return false to avoid
62
63
// accidentally using handles with the same class outside the draggable element
63
- if (elementAtPosition === event .target ) return false ;
64
+ if (elementAtPosition .classList .contains (" draggable-item" ))
65
+ return false ;
64
66
return null ;
65
67
},
66
68
null
@@ -106,7 +108,8 @@ const onDragStart = (itemIndex: number, event: DragEvent) => {
106
108
// If we only want to start dragging if the user clicked on a handle element
107
109
if (props .handleClass ) {
108
110
// If no handle was clicked, we don't want to start dragging the element
109
- if (! hasHandleAtPosition (event )) return ;
111
+ if (! hasHandleAtPosition (event ))
112
+ return ;
110
113
}
111
114
112
115
// Set the effect of moving an element, which by default is clone. Not being used right now
@@ -248,10 +251,25 @@ const hasSlotContent = (slot: SlotType | undefined, slotProps = {}) => {
248
251
});
249
252
};
250
253
251
- const onTouchStart = () => {
254
+ const onTouchStart = (event : TouchEvent ) => {
252
255
touching .value = true ;
253
256
touchDragging .value = false ;
254
257
258
+ // When we use handles, we need to find the element that is the handle, up until the draggable-item element itself
259
+ if (props .handleClass ) {
260
+ let handleElement = event .target as HTMLElement | null ;
261
+ while (handleElement && ! handleElement .classList .contains (props .handleClass )) {
262
+ if (handleElement .classList .contains (" draggable-item" )) {
263
+ handleElement = null ;
264
+ break ;
265
+ }
266
+ handleElement = handleElement .parentElement ;
267
+ }
268
+ // If the user is touching the handle, set isDraggable to true so dragging is allowed to start in onDragStart
269
+ if (handleElement )
270
+ isDraggable .value = true ;
271
+ }
272
+
255
273
if (touchingTimeout .value ) clearTimeout (touchingTimeout .value );
256
274
257
275
touchingTimeout .value = setTimeout (() => {
@@ -262,8 +280,12 @@ const onTouchStart = () => {
262
280
const onTouchEnd = () => {
263
281
touching .value = false ;
264
282
touchDragging .value = false ;
283
+ // When we use handles, isDragging should default to false, so the user has to start dragging the handle for isDragging to be changed to true
284
+ if (props .handleClass )
285
+ isDraggable .value = false ;
265
286
266
- if (touchingTimeout .value ) clearTimeout (touchingTimeout .value );
287
+ if (touchingTimeout .value )
288
+ clearTimeout (touchingTimeout .value );
267
289
touchingTimeout .value = null ;
268
290
};
269
291
</script >
@@ -304,7 +326,7 @@ window.addEventListener("touchmove", () => {});
304
326
"
305
327
@mousedown =" onMouseDown(itemIndex, $event)"
306
328
@mouseup =" onMouseUp(itemIndex, $event)"
307
- @touchstart.passive =" onTouchStart()"
329
+ @touchstart.passive =" onTouchStart($event )"
308
330
@touchend =" onTouchEnd()"
309
331
@dragstart =" onDragStart(itemIndex, $event)"
310
332
@dragenter.prevent
@@ -338,6 +360,7 @@ window.addEventListener("touchmove", () => {});
338
360
}
339
361
.draggable-item .draggable-handle {
340
362
cursor : move ;
363
+ user-select : none ;
341
364
}
342
365
.empty-list-placeholder {
343
366
flex : 1 ;
0 commit comments