Skip to content

Commit 1708941

Browse files
committed
fix: dragging with handles wasn't working
1 parent 380cc05 commit 1708941

File tree

1 file changed

+30
-7
lines changed

1 file changed

+30
-7
lines changed

Diff for: src/components/DraggableList.vue

+30-7
Original file line numberDiff line numberDiff line change
@@ -49,18 +49,20 @@ onMounted(() => {
4949
const emit = defineEmits(["update:list", "start", "end", "update"]);
5050
5151
const hasHandleAtPosition = (event: MouseEvent | DragEvent) => {
52-
const { x, y } = event;
52+
let { clientX: x, clientY: y } = event;
5353
const elementsAtPosition = document.elementsFromPoint(x, y);
5454
return elementsAtPosition.reduce<boolean | null>(
5555
(clickedHandle, elementAtPosition) => {
5656
// If we already have a boolean result, return that
57-
if (typeof clickedHandle === "boolean") return clickedHandle;
57+
if (typeof clickedHandle === "boolean")
58+
return clickedHandle;
5859
// If the clicked element (or one of its parents) has the handle class, we clicked the handle
5960
if (elementAtPosition.classList.contains(props.handleClass!))
6061
return true;
6162
// If we've reached the draggable element itself, we found no handle, so return false to avoid
6263
// 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;
6466
return null;
6567
},
6668
null
@@ -106,7 +108,8 @@ const onDragStart = (itemIndex: number, event: DragEvent) => {
106108
// If we only want to start dragging if the user clicked on a handle element
107109
if (props.handleClass) {
108110
// 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;
110113
}
111114
112115
// 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 = {}) => {
248251
});
249252
};
250253
251-
const onTouchStart = () => {
254+
const onTouchStart = (event: TouchEvent) => {
252255
touching.value = true;
253256
touchDragging.value = false;
254257
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+
255273
if (touchingTimeout.value) clearTimeout(touchingTimeout.value);
256274
257275
touchingTimeout.value = setTimeout(() => {
@@ -262,8 +280,12 @@ const onTouchStart = () => {
262280
const onTouchEnd = () => {
263281
touching.value = false;
264282
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;
265286
266-
if (touchingTimeout.value) clearTimeout(touchingTimeout.value);
287+
if (touchingTimeout.value)
288+
clearTimeout(touchingTimeout.value);
267289
touchingTimeout.value = null;
268290
};
269291
</script>
@@ -304,7 +326,7 @@ window.addEventListener("touchmove", () => {});
304326
"
305327
@mousedown="onMouseDown(itemIndex, $event)"
306328
@mouseup="onMouseUp(itemIndex, $event)"
307-
@touchstart.passive="onTouchStart()"
329+
@touchstart.passive="onTouchStart($event)"
308330
@touchend="onTouchEnd()"
309331
@dragstart="onDragStart(itemIndex, $event)"
310332
@dragenter.prevent
@@ -338,6 +360,7 @@ window.addEventListener("touchmove", () => {});
338360
}
339361
.draggable-item .draggable-handle {
340362
cursor: move;
363+
user-select: none;
341364
}
342365
.empty-list-placeholder {
343366
flex: 1;

0 commit comments

Comments
 (0)