feat(nodes): add effect scope to useDrag utility
This commit is contained in:
@@ -22,130 +22,138 @@ interface UseDragParams {
|
||||
}
|
||||
|
||||
function useDrag(params: UseDragParams) {
|
||||
const {
|
||||
viewport,
|
||||
snapToGrid,
|
||||
snapGrid,
|
||||
nodes,
|
||||
nodeExtent,
|
||||
getNode,
|
||||
multiSelectionActive,
|
||||
selectNodesOnDrag,
|
||||
removeSelectedElements,
|
||||
addSelectedNodes,
|
||||
setState,
|
||||
updateNodePositions,
|
||||
} = $(useVueFlow())
|
||||
const { onStart, onDrag, onStop, el, disabled = false, noDragClassName, id, handleSelector } = $(params)
|
||||
|
||||
const dragging = ref(false)
|
||||
let dragItems = $ref<NodeDragItem[]>()
|
||||
let lastPos = $ref<Partial<XYPosition>>({ x: undefined, y: undefined })
|
||||
let dragHandler = $ref<any>()
|
||||
|
||||
const getMousePosition = (event: UseDragEvent) => {
|
||||
const x = event.sourceEvent.touches ? event.sourceEvent.touches[0].clientX : event.sourceEvent.clientX
|
||||
const y = event.sourceEvent.touches ? event.sourceEvent.touches[0].clientY : event.sourceEvent.clientY
|
||||
|
||||
return pointToRendererPoint(
|
||||
{
|
||||
x,
|
||||
y,
|
||||
},
|
||||
const scope = effectScope()
|
||||
const dragging = scope.run(() => {
|
||||
const {
|
||||
viewport,
|
||||
snapToGrid,
|
||||
snapGrid,
|
||||
)
|
||||
}
|
||||
nodes,
|
||||
nodeExtent,
|
||||
getNode,
|
||||
multiSelectionActive,
|
||||
selectNodesOnDrag,
|
||||
removeSelectedElements,
|
||||
addSelectedNodes,
|
||||
setState,
|
||||
updateNodePositions,
|
||||
} = $(useVueFlow())
|
||||
|
||||
watch(
|
||||
[() => disabled, () => noDragClassName, () => id, () => el],
|
||||
() => {
|
||||
if (el) {
|
||||
const selection = select(el)
|
||||
const node = id ? getNode(id) : undefined
|
||||
const { onStart, onDrag, onStop, el, disabled = false, noDragClassName, id, handleSelector } = $(params)
|
||||
|
||||
if (disabled) {
|
||||
selection.on('.drag', null)
|
||||
} else {
|
||||
dragHandler = drag()
|
||||
.on('start', (event: UseDragEvent) => {
|
||||
if (!selectNodesOnDrag && !multiSelectionActive && id) {
|
||||
if (!node?.selected) {
|
||||
removeSelectedElements()
|
||||
const dragging = ref(false)
|
||||
let dragItems = $ref<NodeDragItem[]>()
|
||||
let lastPos = $ref<Partial<XYPosition>>({ x: undefined, y: undefined })
|
||||
let dragHandler = $ref<any>()
|
||||
|
||||
const getMousePosition = (event: UseDragEvent) => {
|
||||
const x = event.sourceEvent.touches ? event.sourceEvent.touches[0].clientX : event.sourceEvent.clientX
|
||||
const y = event.sourceEvent.touches ? event.sourceEvent.touches[0].clientY : event.sourceEvent.clientY
|
||||
|
||||
return pointToRendererPoint(
|
||||
{
|
||||
x,
|
||||
y,
|
||||
},
|
||||
viewport,
|
||||
snapToGrid,
|
||||
snapGrid,
|
||||
)
|
||||
}
|
||||
|
||||
watch(
|
||||
[() => disabled, () => noDragClassName, () => id, () => el],
|
||||
() => {
|
||||
if (el) {
|
||||
const selection = select(el)
|
||||
const node = id ? getNode(id) : undefined
|
||||
|
||||
if (disabled) {
|
||||
selection.on('.drag', null)
|
||||
} else {
|
||||
dragHandler = drag()
|
||||
.on('start', (event: UseDragEvent) => {
|
||||
if (!selectNodesOnDrag && !multiSelectionActive && id) {
|
||||
if (!node?.selected) {
|
||||
removeSelectedElements()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (node && !disabled && selectNodesOnDrag) {
|
||||
handleNodeClick(node, multiSelectionActive, addSelectedNodes, removeSelectedElements, setState)
|
||||
}
|
||||
if (node && !disabled && selectNodesOnDrag) {
|
||||
handleNodeClick(node, multiSelectionActive, addSelectedNodes, removeSelectedElements, setState)
|
||||
}
|
||||
|
||||
const mousePos = getMousePosition(event)
|
||||
dragItems = getDragItems(nodes, mousePos, getNode, id)
|
||||
const mousePos = getMousePosition(event)
|
||||
dragItems = getDragItems(nodes, mousePos, getNode, id)
|
||||
|
||||
if (onStart && dragItems) {
|
||||
const [currentNode, nodes] = getEventHandlerParams({
|
||||
id,
|
||||
dragItems,
|
||||
getNode: $$(getNode),
|
||||
})
|
||||
onStart(event.sourceEvent, currentNode, nodes)
|
||||
}
|
||||
})
|
||||
.on('drag', (event: UseDragEvent) => {
|
||||
const mousePos = getMousePosition(event)
|
||||
|
||||
// skip events without movement
|
||||
if ((lastPos.x !== mousePos.x || lastPos.y !== mousePos.y) && dragItems) {
|
||||
lastPos = mousePos
|
||||
dragItems = dragItems.map((n) =>
|
||||
updatePosition(n, mousePos, n.parentNode ? getNode(n.parentNode) : undefined, nodeExtent),
|
||||
)
|
||||
|
||||
updateNodePositions(dragItems, true, true)
|
||||
dragging.value = true
|
||||
|
||||
if (onDrag) {
|
||||
if (onStart && dragItems) {
|
||||
const [currentNode, nodes] = getEventHandlerParams({
|
||||
id,
|
||||
dragItems,
|
||||
getNode: $$(getNode),
|
||||
})
|
||||
onDrag(event.sourceEvent, currentNode, nodes)
|
||||
}
|
||||
}
|
||||
|
||||
event.on('end', (event) => {
|
||||
dragging.value = false
|
||||
if (onStop && dragItems) {
|
||||
updateNodePositions(dragItems, false, false)
|
||||
|
||||
const [currentNode, nodes] = getEventHandlerParams({
|
||||
id,
|
||||
dragItems,
|
||||
getNode: $$(getNode),
|
||||
})
|
||||
onStop(event.sourceEvent, currentNode, nodes)
|
||||
onStart(event.sourceEvent, currentNode, nodes)
|
||||
}
|
||||
})
|
||||
})
|
||||
.filter((event: D3DragEvent<HTMLDivElement, null, SubjectPosition>['sourceEvent']) => {
|
||||
const target = event.target as HTMLDivElement
|
||||
return (
|
||||
!event.ctrlKey &&
|
||||
!event.button &&
|
||||
(!noDragClassName ||
|
||||
(!hasSelector(target, `.${noDragClassName}`, $$(el)) &&
|
||||
(!handleSelector || hasSelector(target, handleSelector, $$(el)))))
|
||||
)
|
||||
})
|
||||
.on('drag', (event: UseDragEvent) => {
|
||||
const mousePos = getMousePosition(event)
|
||||
|
||||
selection.call(dragHandler)
|
||||
// skip events without movement
|
||||
if ((lastPos.x !== mousePos.x || lastPos.y !== mousePos.y) && dragItems) {
|
||||
lastPos = mousePos
|
||||
dragItems = dragItems.map((n) =>
|
||||
updatePosition(n, mousePos, n.parentNode ? getNode(n.parentNode) : undefined, nodeExtent),
|
||||
)
|
||||
|
||||
updateNodePositions(dragItems, true, true)
|
||||
dragging.value = true
|
||||
|
||||
if (onDrag) {
|
||||
const [currentNode, nodes] = getEventHandlerParams({
|
||||
id,
|
||||
dragItems,
|
||||
getNode: $$(getNode),
|
||||
})
|
||||
onDrag(event.sourceEvent, currentNode, nodes)
|
||||
}
|
||||
}
|
||||
|
||||
event.on('end', (event) => {
|
||||
dragging.value = false
|
||||
if (onStop && dragItems) {
|
||||
updateNodePositions(dragItems, false, false)
|
||||
|
||||
const [currentNode, nodes] = getEventHandlerParams({
|
||||
id,
|
||||
dragItems,
|
||||
getNode: $$(getNode),
|
||||
})
|
||||
onStop(event.sourceEvent, currentNode, nodes)
|
||||
}
|
||||
})
|
||||
})
|
||||
.filter((event: D3DragEvent<HTMLDivElement, null, SubjectPosition>['sourceEvent']) => {
|
||||
const target = event.target as HTMLDivElement
|
||||
return (
|
||||
!event.ctrlKey &&
|
||||
!event.button &&
|
||||
(!noDragClassName ||
|
||||
(!hasSelector(target, `.${noDragClassName}`, $$(el)) &&
|
||||
(!handleSelector || hasSelector(target, handleSelector, $$(el)))))
|
||||
)
|
||||
})
|
||||
|
||||
selection.call(dragHandler)
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{ flush: 'post' },
|
||||
)
|
||||
},
|
||||
{ flush: 'post' },
|
||||
)
|
||||
|
||||
return dragging
|
||||
})
|
||||
|
||||
tryOnScopeDispose(() => scope.stop())
|
||||
|
||||
return dragging
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user