@@ -74,9 +74,10 @@ export interface NodeProps<T = any> extends NodeDragEvents<NodeData<T>, PortData
7474 icon : ReactElement < IconProps , typeof Icon > ;
7575 label : ReactElement < LabelProps , typeof Label > ;
7676 port : ReactElement < PortProps , typeof Port > ;
77+ tooltip ?: React . ElementType ;
7778}
7879
79- export const Node : FC < Partial < NodeProps > > = ( { id, x, y, ports, labels, height, width, properties, animated, className, rx = 2 , ry = 2 , offsetX = 0 , offsetY = 0 , icon, disabled, style, children, nodes, edges, draggable = true , linkable = true , selectable = true , removable = true , dragType = 'multiportOnly' , dragCursor = 'crosshair' , childEdge = < Edge /> , childNode = < Node /> , remove = < Remove /> , port = < Port /> , label = < Label /> , onRemove, onDrag, onDragStart, onDragEnd, onClick, onKeyDown, onEnter, onLeave } ) => {
80+ export const Node : FC < Partial < NodeProps > > = ( { id, x, y, ports, labels, height, width, properties, animated, className, rx = 2 , ry = 2 , offsetX = 0 , offsetY = 0 , icon, disabled, style, children, nodes, edges, draggable = true , linkable = true , selectable = true , removable = true , dragType = 'multiportOnly' , dragCursor = 'crosshair' , childEdge = < Edge /> , childNode = < Node /> , remove = < Remove /> , port = < Port /> , label = < Label /> , tooltip : Tooltip = React . Fragment , onRemove, onDrag, onDragStart, onDragEnd, onClick, onKeyDown, onEnter, onLeave } ) => {
8081 const nodeRef = useRef < SVGRectElement | null > ( null ) ;
8182 const controls = useAnimation ( ) ;
8283 const { canLinkNode, enteredNode, selections, readonly, ...canvas } = useCanvas ( ) ;
@@ -287,86 +288,92 @@ export const Node: FC<Partial<NodeProps>> = ({ id, x, y, ports, labels, height,
287288 } }
288289 animate = { controls }
289290 >
290- < motion . rect
291- { ...bind ( ) }
292- ref = { nodeRef }
293- tabIndex = { - 1 }
294- onKeyDown = { onKeyDownCallback }
295- onClick = { onClickCallback }
296- onTouchStart = { onTouchStartCallback }
297- onMouseEnter = { onMouseEnterCallback }
298- onMouseLeave = { onMouseLeaveCallback }
299- className = { classNames ( css . rect , className , properties ?. className , {
300- [ css . active ] : isActive ,
301- [ css . disabled ] : isDisabled ,
302- [ css . unlinkable ] : isLinkable === false && ! isNodeDrag ,
303- [ css . dragging ] : dragging ,
304- [ css . children ] : nodes ?. length > 0 ,
305- [ css . deleteHovered ] : deleteHovered ,
306- [ css . selectionDisabled ] : ! canSelect
307- } ) }
308- style = { style }
309- height = { height }
310- width = { width }
311- rx = { rx }
312- ry = { ry }
313- initial = { {
314- opacity : 0
315- } }
316- animate = { {
317- opacity : 1 ,
318- transition : ! animated ? { type : false , duration : 0 } : { }
319- } }
320- />
321- { children && < Fragment > { typeof children === 'function' ? ( children as NodeChildrenAsFunction ) ( nodeChildProps ) : children } </ Fragment > }
322- { icon && properties . icon && < CloneElement < IconProps > element = { icon } { ...properties . icon } /> }
323- { label && labels ?. length > 0 && labels . map ( ( l , index ) => < CloneElement < LabelProps > element = { label } key = { index } { ...( l as LabelProps ) } /> ) }
324- { port && ports ?. length > 0 && ports . map ( ( p ) => < CloneElement < PortProps > element = { port } key = { p . id } active = { ! isMultiPort && dragging } disabled = { isDisabled || ! linkable } offsetX = { newX } offsetY = { newY } onDragStart = { onDragStartCallback } onDrag = { onDragCallback } onDragEnd = { onDragEndCallback } { ...( p as PortProps ) } id = { `${ id } -port-${ p . id } ` } /> ) }
325- { ! isDisabled && isActive && ! readonly && remove && removable && (
326- < CloneElement < RemoveProps >
327- element = { remove }
328- y = { height / 2 }
329- x = { width }
330- onClick = { ( event : React . MouseEvent < SVGGElement , MouseEvent > ) => {
331- event . preventDefault ( ) ;
332- event . stopPropagation ( ) ;
333- onRemove ?.( event , properties ) ;
334- setDeleteHovered ( false ) ;
335- } }
336- onEnter = { ( ) => setDeleteHovered ( true ) }
337- onLeave = { ( ) => setDeleteHovered ( false ) }
338- />
339- ) }
340- < g >
341- { edges ?. length > 0 &&
342- edges . map ( ( e : any ) => {
343- const element = typeof childEdge === 'function' ? childEdge ( e ) : childEdge ;
344- return (
345- < CloneElement < EdgeProps >
346- key = { e . id }
347- element = { element }
348- id = { `${ id } -edge-${ e . id } ` }
349- disabled = { isDisabled }
350- { ...e }
351- properties = { {
352- ...e . properties ,
353- ...( e . data ? { data : e . data } : { } )
291+ < foreignObject width = { width } height = { height } style = { { pointerEvents : 'none' } } >
292+ < Tooltip >
293+ < svg width = { width } height = { height } >
294+ < motion . rect
295+ { ...bind ( ) }
296+ ref = { nodeRef }
297+ tabIndex = { - 1 }
298+ onKeyDown = { onKeyDownCallback }
299+ onClick = { onClickCallback }
300+ onTouchStart = { onTouchStartCallback }
301+ onMouseEnter = { onMouseEnterCallback }
302+ onMouseLeave = { onMouseLeaveCallback }
303+ className = { classNames ( css . rect , className , properties ?. className , {
304+ [ css . active ] : isActive ,
305+ [ css . disabled ] : isDisabled ,
306+ [ css . unlinkable ] : isLinkable === false && ! isNodeDrag ,
307+ [ css . dragging ] : dragging ,
308+ [ css . children ] : nodes ?. length > 0 ,
309+ [ css . deleteHovered ] : deleteHovered ,
310+ [ css . selectionDisabled ] : ! canSelect
311+ } ) }
312+ style = { { ...style , pointerEvents : 'auto' } }
313+ height = { height }
314+ width = { width }
315+ rx = { rx }
316+ ry = { ry }
317+ initial = { {
318+ opacity : 1
319+ } }
320+ animate = { {
321+ opacity : 1 ,
322+ transition : ! animated ? { type : false , duration : 0 } : { }
323+ } }
324+ />
325+ { children && < Fragment > { typeof children === 'function' ? ( children as NodeChildrenAsFunction ) ( nodeChildProps ) : children } </ Fragment > }
326+ { icon && properties . icon && < CloneElement < IconProps > element = { icon } { ...properties . icon } /> }
327+ { label && labels ?. length > 0 && labels . map ( ( l , index ) => < CloneElement < LabelProps > element = { label } key = { index } { ...( l as LabelProps ) } /> ) }
328+ { port && ports ?. length > 0 && ports . map ( ( p ) => < CloneElement < PortProps > element = { port } key = { p . id } active = { ! isMultiPort && dragging } disabled = { isDisabled || ! linkable } offsetX = { newX } offsetY = { newY } onDragStart = { onDragStartCallback } onDrag = { onDragCallback } onDragEnd = { onDragEndCallback } { ...( p as PortProps ) } id = { `${ id } -port-${ p . id } ` } /> ) }
329+ { ! isDisabled && isActive && ! readonly && remove && removable && (
330+ < CloneElement < RemoveProps >
331+ element = { remove }
332+ y = { height / 2 }
333+ x = { width }
334+ onClick = { ( event : React . MouseEvent < SVGGElement , MouseEvent > ) => {
335+ event . preventDefault ( ) ;
336+ event . stopPropagation ( ) ;
337+ onRemove ?.( event , properties ) ;
338+ setDeleteHovered ( false ) ;
354339 } }
340+ onEnter = { ( ) => setDeleteHovered ( true ) }
341+ onLeave = { ( ) => setDeleteHovered ( false ) }
355342 />
356- ) ;
357- } ) }
358- { nodes ?. length > 0 &&
359- nodes . map ( ( { children, ...n } : any ) => {
360- const element = typeof childNode === 'function' ? childNode ( n ) : childNode ;
361- const elementDisabled = element . props ?. disabled != null ? element . props . disabled : disabled ;
362- const elementAnimated = element . props ?. animated != null ? element . props . animated : animated ;
363- const elementDraggable = element . props ?. draggable != null ? element . props . draggable : draggable ;
364- const elementLinkable = element . props ?. linkable != null ? element . props . linkable : linkable ;
365- const elementSelectable = element . props ?. selectable != null ? element . props . selectable : selectable ;
366- const elementRemovable = element . props ?. removable != null ? element . props . removable : removable ;
367- return < CloneElement < NodeProps > key = { n . id } element = { element } id = { `${ id } -node-${ n . id } ` } disabled = { elementDisabled } nodes = { children } offsetX = { newX } offsetY = { newY } animated = { elementAnimated } children = { element . props . children } childNode = { childNode } dragCursor = { dragCursor } dragType = { dragType } childEdge = { childEdge } draggable = { elementDraggable } linkable = { elementLinkable } selectable = { elementSelectable } removable = { elementRemovable } onDragStart = { onDragStart } onDrag = { onDrag } onDragEnd = { onDragEnd } onClick = { onClick } onEnter = { onEnter } onLeave = { onLeave } onKeyDown = { onKeyDown } onRemove = { onRemove } { ...n } /> ;
368- } ) }
369- </ g >
343+ ) }
344+ < g >
345+ { edges ?. length > 0 &&
346+ edges . map ( ( e : any ) => {
347+ const element = typeof childEdge === 'function' ? childEdge ( e ) : childEdge ;
348+ return (
349+ < CloneElement < EdgeProps >
350+ key = { e . id }
351+ element = { element }
352+ id = { `${ id } -edge-${ e . id } ` }
353+ disabled = { isDisabled }
354+ { ...e }
355+ properties = { {
356+ ...e . properties ,
357+ ...( e . data ? { data : e . data } : { } )
358+ } }
359+ />
360+ ) ;
361+ } ) }
362+ { nodes ?. length > 0 &&
363+ nodes . map ( ( { children, ...n } : any ) => {
364+ const element = typeof childNode === 'function' ? childNode ( n ) : childNode ;
365+ const elementDisabled = element . props ?. disabled != null ? element . props . disabled : disabled ;
366+ const elementAnimated = element . props ?. animated != null ? element . props . animated : animated ;
367+ const elementDraggable = element . props ?. draggable != null ? element . props . draggable : draggable ;
368+ const elementLinkable = element . props ?. linkable != null ? element . props . linkable : linkable ;
369+ const elementSelectable = element . props ?. selectable != null ? element . props . selectable : selectable ;
370+ const elementRemovable = element . props ?. removable != null ? element . props . removable : removable ;
371+ return < CloneElement < NodeProps > key = { n . id } element = { element } id = { `${ id } -node-${ n . id } ` } disabled = { elementDisabled } nodes = { children } offsetX = { newX } offsetY = { newY } animated = { elementAnimated } children = { element . props . children } childNode = { childNode } dragCursor = { dragCursor } dragType = { dragType } childEdge = { childEdge } draggable = { elementDraggable } linkable = { elementLinkable } selectable = { elementSelectable } removable = { elementRemovable } onDragStart = { onDragStart } onDrag = { onDrag } onDragEnd = { onDragEnd } onClick = { onClick } onEnter = { onEnter } onLeave = { onLeave } onKeyDown = { onKeyDown } onRemove = { onRemove } { ...n } /> ;
372+ } ) }
373+ </ g >
374+ </ svg >
375+ </ Tooltip >
376+ </ foreignObject >
370377 </ motion . g >
371378 ) ;
372379} ;
0 commit comments