| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164 |
- import type { MouseEvent } from 'react'
- import {
- useCallback,
- } from 'react'
- import produce from 'immer'
- import type {
- OnSelectionChangeFunc,
- } from 'reactflow'
- import { useStoreApi } from 'reactflow'
- import { useWorkflowStore } from '../store'
- import type { Node } from '../types'
-
- export const useSelectionInteractions = () => {
- const store = useStoreApi()
- const workflowStore = useWorkflowStore()
-
- const handleSelectionStart = useCallback(() => {
- const {
- getNodes,
- setNodes,
- edges,
- setEdges,
- userSelectionRect,
- } = store.getState()
-
- if (!userSelectionRect?.width || !userSelectionRect?.height) {
- const nodes = getNodes()
- const newNodes = produce(nodes, (draft) => {
- draft.forEach((node) => {
- if (node.data._isBundled)
- node.data._isBundled = false
- })
- })
- setNodes(newNodes)
- const newEdges = produce(edges, (draft) => {
- draft.forEach((edge) => {
- if (edge.data._isBundled)
- edge.data._isBundled = false
- })
- })
- setEdges(newEdges)
- }
- }, [store])
-
- const handleSelectionChange = useCallback<OnSelectionChangeFunc>(({ nodes: nodesInSelection, edges: edgesInSelection }) => {
- const {
- getNodes,
- setNodes,
- edges,
- setEdges,
- userSelectionRect,
- } = store.getState()
-
- const nodes = getNodes()
-
- if (!userSelectionRect?.width || !userSelectionRect?.height)
- return
-
- const newNodes = produce(nodes, (draft) => {
- draft.forEach((node) => {
- const nodeInSelection = nodesInSelection.find(n => n.id === node.id)
-
- if (nodeInSelection)
- node.data._isBundled = true
- else
- node.data._isBundled = false
- })
- })
- setNodes(newNodes)
- const newEdges = produce(edges, (draft) => {
- draft.forEach((edge) => {
- const edgeInSelection = edgesInSelection.find(e => e.id === edge.id)
-
- if (edgeInSelection)
- edge.data._isBundled = true
- else
- edge.data._isBundled = false
- })
- })
- setEdges(newEdges)
- }, [store])
-
- const handleSelectionDrag = useCallback((_: MouseEvent, nodesWithDrag: Node[]) => {
- const {
- getNodes,
- setNodes,
- } = store.getState()
-
- workflowStore.setState({
- nodeAnimation: false,
- })
- const nodes = getNodes()
- const newNodes = produce(nodes, (draft) => {
- draft.forEach((node) => {
- const dragNode = nodesWithDrag.find(n => n.id === node.id)
-
- if (dragNode)
- node.position = dragNode.position
- })
- })
- setNodes(newNodes)
- }, [store, workflowStore])
-
- const handleSelectionCancel = useCallback(() => {
- const {
- getNodes,
- setNodes,
- edges,
- setEdges,
- } = store.getState()
-
- store.setState({
- userSelectionRect: null,
- userSelectionActive: true,
- })
-
- const nodes = getNodes()
- const newNodes = produce(nodes, (draft) => {
- draft.forEach((node) => {
- if (node.data._isBundled)
- node.data._isBundled = false
- })
- })
- setNodes(newNodes)
- const newEdges = produce(edges, (draft) => {
- draft.forEach((edge) => {
- if (edge.data._isBundled)
- edge.data._isBundled = false
- })
- })
- setEdges(newEdges)
- }, [store])
-
- const handleSelectionContextMenu = useCallback((e: MouseEvent) => {
- const target = e.target as HTMLElement
- if (!target.classList.contains('react-flow__nodesselection-rect'))
- return
-
- e.preventDefault()
- const container = document.querySelector('#workflow-container')
- const { x, y } = container!.getBoundingClientRect()
- workflowStore.setState({
- selectionMenu: {
- top: e.clientY - y,
- left: e.clientX - x,
- },
- })
- }, [workflowStore])
-
- const handleSelectionContextmenuCancel = useCallback(() => {
- workflowStore.setState({
- selectionMenu: undefined,
- })
- }, [workflowStore])
-
- return {
- handleSelectionStart,
- handleSelectionChange,
- handleSelectionDrag,
- handleSelectionCancel,
- handleSelectionContextMenu,
- handleSelectionContextmenuCancel,
- }
- }
|