-
-
Notifications
You must be signed in to change notification settings - Fork 447
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix(web): Simplify the logic for tag drag and dropping
- Loading branch information
1 parent
1fee129
commit e5fd9ee
Showing
3 changed files
with
68 additions
and
127 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,89 +1,48 @@ | ||
import React from "react"; | ||
import { DraggableData, DraggableEvent } from "react-draggable"; | ||
|
||
export interface DragState { | ||
// The id of the element that is being dragged | ||
dragSourceId: string | null; | ||
// The id of the element that is currently being hovered over | ||
dragTargetId: string | null; | ||
// The position of the elements being dragged such that on drag over, we can revert the position. | ||
initialX: number; | ||
initialY: number; | ||
} | ||
|
||
export interface DragAndDropFunctions { | ||
handleDragStart: (e: DraggableEvent, data: DraggableData) => void; | ||
handleDrag: (e: DraggableEvent) => void; | ||
handleDragEnd: () => void; | ||
dragState: DragState; | ||
} | ||
|
||
export function useDragAndDrop( | ||
dragSourceIdAttribute: string, | ||
dragTargetIdAttribute: string, | ||
callback: (dragSourceId: string, dragTargetId: string) => void, | ||
): DragAndDropFunctions { | ||
const initialState: DragState = { | ||
dragSourceId: null, | ||
dragTargetId: null, | ||
initialX: 0, | ||
initialY: 0, | ||
}; | ||
|
||
let currentState: DragState = initialState; | ||
|
||
function handleDragStart(e: DraggableEvent, data: DraggableData): void { | ||
const { node } = data; | ||
const id = node.getAttribute(dragSourceIdAttribute); | ||
|
||
currentState = { | ||
...initialState, | ||
dragSourceId: id, | ||
initialX: data.x, | ||
initialY: data.y, | ||
}; | ||
} | ||
|
||
function handleDrag(e: DraggableEvent): void { | ||
const { dragTargetId } = currentState; | ||
const { target } = e; | ||
|
||
// Important according to the sample I found | ||
e.preventDefault(); | ||
|
||
if (target) { | ||
const id = (target as HTMLElement).getAttribute(dragTargetIdAttribute); | ||
|
||
if (id !== dragTargetId) { | ||
currentState.dragTargetId = id; | ||
} | ||
} | ||
} | ||
|
||
function handleDragEnd(): void { | ||
const { dragSourceId, dragTargetId } = currentState; | ||
|
||
if (dragSourceId && dragTargetId && dragSourceId !== dragTargetId) { | ||
/* | ||
onDragOver: (dragSourceId: string, dragTargetId: string) => void, | ||
) { | ||
const [dragSourceId, setDragSourceId] = React.useState<string | null>(null); | ||
|
||
const handleDragStart = React.useCallback( | ||
(_e: DraggableEvent, { node }: DraggableData) => { | ||
const id = node.getAttribute(dragSourceIdAttribute); | ||
setDragSourceId(id); | ||
}, | ||
[], | ||
); | ||
|
||
const handleDragEnd = React.useCallback( | ||
(e: DraggableEvent) => { | ||
const { target } = e; | ||
const dragTargetId = (target as HTMLElement).getAttribute( | ||
dragTargetIdAttribute, | ||
); | ||
|
||
if (dragSourceId && dragTargetId && dragSourceId !== dragTargetId) { | ||
/* | ||
As Draggable tries to setState when the | ||
component is unmounted, it is needed to | ||
push onCombine to the event loop queue. | ||
onCombine would be run after setState on | ||
Draggable so it would fix the issue until | ||
they fix it on their end. | ||
*/ | ||
setTimeout(() => { | ||
console.log(dragSourceId, dragTargetId); | ||
callback(dragSourceId, dragTargetId); | ||
}, 0); | ||
} | ||
|
||
currentState = initialState; | ||
} | ||
setTimeout(() => { | ||
onDragOver(dragSourceId, dragTargetId); | ||
}, 0); | ||
} | ||
setDragSourceId(null); | ||
}, | ||
[dragSourceId, onDragOver], | ||
); | ||
|
||
return { | ||
dragState: currentState, | ||
handleDragStart, | ||
handleDrag, | ||
handleDragEnd, | ||
}; | ||
} |