Skip to content

Commit

Permalink
fix: dragging with handles wasn't working
Browse files Browse the repository at this point in the history
  • Loading branch information
KrisVos130 committed Jun 15, 2024
1 parent 380cc05 commit 1708941
Showing 1 changed file with 30 additions and 7 deletions.
37 changes: 30 additions & 7 deletions src/components/DraggableList.vue
Original file line number Diff line number Diff line change
Expand Up @@ -49,18 +49,20 @@ onMounted(() => {
const emit = defineEmits(["update:list", "start", "end", "update"]);
const hasHandleAtPosition = (event: MouseEvent | DragEvent) => {
const { x, y } = event;
let { clientX: x, clientY: y } = event;
const elementsAtPosition = document.elementsFromPoint(x, y);
return elementsAtPosition.reduce<boolean | null>(
(clickedHandle, elementAtPosition) => {
// If we already have a boolean result, return that
if (typeof clickedHandle === "boolean") return clickedHandle;
if (typeof clickedHandle === "boolean")

Check failure on line 57 in src/components/DraggableList.vue

View workflow job for this annotation

GitHub Actions / build

Delete `⏎···············`
return clickedHandle;
// If the clicked element (or one of its parents) has the handle class, we clicked the handle
if (elementAtPosition.classList.contains(props.handleClass!))
return true;
// If we've reached the draggable element itself, we found no handle, so return false to avoid
// accidentally using handles with the same class outside the draggable element
if (elementAtPosition === event.target) return false;
if (elementAtPosition.classList.contains("draggable-item"))
return false;
return null;
},
null
Expand Down Expand Up @@ -106,7 +108,8 @@ const onDragStart = (itemIndex: number, event: DragEvent) => {
// If we only want to start dragging if the user clicked on a handle element
if (props.handleClass) {
// If no handle was clicked, we don't want to start dragging the element
if (!hasHandleAtPosition(event)) return;
if (!hasHandleAtPosition(event))

Check failure on line 111 in src/components/DraggableList.vue

View workflow job for this annotation

GitHub Actions / build

Delete `⏎···········`
return;
}
// Set the effect of moving an element, which by default is clone. Not being used right now
Expand Down Expand Up @@ -248,10 +251,25 @@ const hasSlotContent = (slot: SlotType | undefined, slotProps = {}) => {
});
};
const onTouchStart = () => {
const onTouchStart = (event: TouchEvent) => {
touching.value = true;
touchDragging.value = false;
// When we use handles, we need to find the element that is the handle, up until the draggable-item element itself
if (props.handleClass) {
let handleElement = event.target as HTMLElement | null;
while (handleElement && !handleElement.classList.contains(props.handleClass)) {

Check failure on line 261 in src/components/DraggableList.vue

View workflow job for this annotation

GitHub Actions / build

Replace `handleElement·&&·!handleElement.classList.contains(props.handleClass)` with `⏎············handleElement·&&⏎············!handleElement.classList.contains(props.handleClass)⏎········`
if (handleElement.classList.contains("draggable-item")) {
handleElement = null;
break;
}
handleElement = handleElement.parentElement;
}
// If the user is touching the handle, set isDraggable to true so dragging is allowed to start in onDragStart
if (handleElement)

Check failure on line 269 in src/components/DraggableList.vue

View workflow job for this annotation

GitHub Actions / build

Delete `⏎···········`
isDraggable.value = true;
}
if (touchingTimeout.value) clearTimeout(touchingTimeout.value);
touchingTimeout.value = setTimeout(() => {
Expand All @@ -262,8 +280,12 @@ const onTouchStart = () => {
const onTouchEnd = () => {
touching.value = false;
touchDragging.value = false;
// 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
if (props.handleClass)

Check failure on line 284 in src/components/DraggableList.vue

View workflow job for this annotation

GitHub Actions / build

Delete `⏎·······`
isDraggable.value = false;
if (touchingTimeout.value) clearTimeout(touchingTimeout.value);
if (touchingTimeout.value)

Check failure on line 287 in src/components/DraggableList.vue

View workflow job for this annotation

GitHub Actions / build

Delete `⏎·······`
clearTimeout(touchingTimeout.value);
touchingTimeout.value = null;
};
</script>
Expand Down Expand Up @@ -304,7 +326,7 @@ window.addEventListener("touchmove", () => {});
"
@mousedown="onMouseDown(itemIndex, $event)"
@mouseup="onMouseUp(itemIndex, $event)"
@touchstart.passive="onTouchStart()"
@touchstart.passive="onTouchStart($event)"
@touchend="onTouchEnd()"
@dragstart="onDragStart(itemIndex, $event)"
@dragenter.prevent
Expand Down Expand Up @@ -338,6 +360,7 @@ window.addEventListener("touchmove", () => {});
}
.draggable-item .draggable-handle {
cursor: move;
user-select: none;
}
.empty-list-placeholder {
flex: 1;
Expand Down

0 comments on commit 1708941

Please sign in to comment.