1
- import React , { memo , useContext } from 'react' ;
1
+ import React , { memo , useState } from 'react' ;
2
2
import { PlusOutlined , CloseOutlined } from '@ant-design/icons' ;
3
3
import { BezierEdge , EdgeLabelRenderer , getBezierPath , useReactFlow } from '@xyflow/react' ;
4
4
import { useShallow } from 'zustand/react/shallow' ;
5
5
import produce from 'immer' ;
6
6
import { uuid } from '../../core/utils' ;
7
7
import useStore from '../../core/store' ;
8
- import { ConfigContext } from '../../models/context' ;
9
8
import NodeSelectPopover from '../NodeSelectPopover' ;
10
9
import './index.less' ;
11
10
12
11
export default memo ( ( edge : any ) => {
13
12
const {
14
- label,
15
13
id,
14
+ selected,
16
15
sourceX,
17
16
sourceY,
18
17
targetX,
19
18
targetY,
20
- data,
21
- selected,
22
19
source,
23
20
target,
24
- layout,
25
21
} = edge ;
26
22
27
- const configCtx : any = useContext ( ConfigContext ) ;
28
-
29
23
const reactflow = useReactFlow ( ) ;
24
+ const [ isHovered , setIsHovered ] = useState ( false ) ;
30
25
const [ edgePath , labelX , labelY ] = getBezierPath ( {
31
26
sourceX,
32
27
sourceY,
@@ -36,29 +31,58 @@ export default memo((edge: any) => {
36
31
37
32
const {
38
33
nodes,
34
+ edges,
39
35
setNodes,
36
+ setEdges,
40
37
mousePosition,
38
+ onEdgesChange,
39
+ layout,
41
40
} = useStore (
42
41
useShallow ( ( state : any ) => ( {
42
+ layout : state . layout ,
43
43
nodes : state . nodes ,
44
+ edges : state . edges ,
44
45
mousePosition : state . mousePosition ,
45
- setNodes : state . setNodes
46
+ setNodes : state . setNodes ,
47
+ setEdges : state . setEdges ,
48
+ onEdgesChange : state . onEdgesChange
46
49
} ) )
47
50
) ;
48
51
49
52
const handleAddNode = ( data : any ) => {
50
53
const { screenToFlowPosition } = reactflow ;
51
54
const { x, y } = screenToFlowPosition ( { x : mousePosition . pageX , y : mousePosition . pageY } ) ;
52
55
56
+
57
+ const targetId = uuid ( ) ;
53
58
const newNodes = produce ( nodes , ( draft : any ) => {
54
59
draft . push ( {
55
- id : uuid ( ) ,
60
+ id : targetId ,
56
61
type : 'custom' ,
57
62
data,
58
63
position : { x, y }
59
64
} ) ;
60
65
} ) ;
66
+
67
+ const newEdges = produce ( edges , ( draft : any ) => {
68
+ draft . push ( ...[
69
+ {
70
+ id : uuid ( ) ,
71
+ source,
72
+ target : targetId ,
73
+ } ,
74
+ {
75
+ id : uuid ( ) ,
76
+ source : targetId ,
77
+ target,
78
+ }
79
+ ] )
80
+
81
+ } ) ;
82
+
61
83
setNodes ( newNodes ) ;
84
+ setEdges ( newEdges ) ;
85
+ onEdgesChange ( [ { id, type : 'remove' } ] ) ;
62
86
} ;
63
87
64
88
let edgeExtra : any = {
@@ -73,32 +97,36 @@ export default memo((edge: any) => {
73
97
}
74
98
75
99
return (
76
- < BezierEdge
77
- { ...edge }
78
- { ...edgeExtra }
79
- selected = { false }
80
- edgePath = { edgePath }
81
- label = {
82
- < EdgeLabelRenderer >
83
- < div
84
- className = 'custom-edge-line'
85
- style = { {
86
- transform : `translate(-50%, -50%) translate(${ labelX } px, ${ labelY } px)` ,
87
- } }
88
- >
89
- < div className = 'line-content' >
90
- < div className = 'icon-box' >
91
- < CloseOutlined style = { { color : '#fff' , fontSize : 12 } } />
100
+ < g
101
+ onMouseEnter = { ( ) => setIsHovered ( true ) }
102
+ onMouseLeave = { ( ) => setIsHovered ( false ) }
103
+ >
104
+ < BezierEdge
105
+ { ...edge }
106
+ { ...edgeExtra }
107
+ edgePath = { edgePath }
108
+ label = {
109
+ isHovered && < EdgeLabelRenderer >
110
+ < div
111
+ className = 'custom-edge-line'
112
+ style = { {
113
+ transform : `translate(-50%, -50%) translate(${ labelX } px,${ labelY } px)` ,
114
+ } }
115
+ >
116
+ < div className = 'line-content' >
117
+ < div className = 'line-icon-box' onClick = { ( ) => onEdgesChange ( [ { id, type : 'remove' } ] ) } >
118
+ < CloseOutlined style = { { color : '#fff' , fontSize : 10 } } />
119
+ </ div >
120
+ < NodeSelectPopover placement = 'right' addNode = { handleAddNode } >
121
+ < div className = 'line-icon-box' >
122
+ < PlusOutlined style = { { color : '#fff' , fontSize : 10 } } />
123
+ </ div >
124
+ </ NodeSelectPopover >
92
125
</ div >
93
- < NodeSelectPopover placement = 'right' addNode = { handleAddNode } >
94
- < div className = 'icon-box' >
95
- < PlusOutlined style = { { color : '#fff' , fontSize : 12 } } />
96
- </ div >
97
- </ NodeSelectPopover >
98
126
</ div >
99
- </ div >
100
- </ EdgeLabelRenderer >
101
- }
102
- / >
127
+ </ EdgeLabelRenderer >
128
+ }
129
+ />
130
+ </ g >
103
131
) ;
104
132
} )
0 commit comments