55 * in a dark-themed, resizable side panel with copy support.
66 */
77
8- import { useCallback , useRef , useState } from 'react'
8+ import { useCallback , useEffect , useRef , useState } from 'react'
99
1010import type { FlowData } from '@flowiseai/agentflow'
1111
@@ -22,37 +22,50 @@ export function FlowStatePanel({ currentFlow, savedFlow, changeCount }: FlowStat
2222 const dragging = useRef ( false )
2323 const flow = tab === 'live' ? currentFlow : savedFlow
2424
25+ const startX = useRef ( 0 )
26+ const startWidth = useRef ( 0 )
27+
2528 const resizeBy = useCallback ( ( delta : number ) => {
2629 setWidth ( ( w ) => Math . max ( 200 , Math . min ( 800 , w + delta ) ) )
2730 } , [ ] )
2831
32+ const onMouseMove = useCallback ( ( moveEvent : MouseEvent ) => {
33+ if ( ! dragging . current ) return
34+ const newWidth = Math . max ( 200 , Math . min ( 800 , startWidth . current + ( startX . current - moveEvent . clientX ) ) )
35+ setWidth ( newWidth )
36+ } , [ ] )
37+
38+ const onMouseUp = useCallback ( ( ) => {
39+ dragging . current = false
40+ document . removeEventListener ( 'mousemove' , onMouseMove )
41+ document . removeEventListener ( 'mouseup' , onMouseUp )
42+ document . body . style . cursor = ''
43+ document . body . style . userSelect = ''
44+ } , [ onMouseMove ] )
45+
46+ // Clean up global listeners on unmount to prevent memory leaks
47+ useEffect ( ( ) => {
48+ return ( ) => {
49+ document . removeEventListener ( 'mousemove' , onMouseMove )
50+ document . removeEventListener ( 'mouseup' , onMouseUp )
51+ document . body . style . cursor = ''
52+ document . body . style . userSelect = ''
53+ }
54+ } , [ onMouseMove , onMouseUp ] )
55+
2956 const handleMouseDown = useCallback (
3057 ( e : React . MouseEvent ) => {
3158 e . preventDefault ( )
3259 dragging . current = true
33- const startX = e . clientX
34- const startWidth = width
35-
36- const onMouseMove = ( moveEvent : MouseEvent ) => {
37- if ( ! dragging . current ) return
38- const newWidth = Math . max ( 200 , Math . min ( 800 , startWidth + ( startX - moveEvent . clientX ) ) )
39- setWidth ( newWidth )
40- }
41-
42- const onMouseUp = ( ) => {
43- dragging . current = false
44- document . removeEventListener ( 'mousemove' , onMouseMove )
45- document . removeEventListener ( 'mouseup' , onMouseUp )
46- document . body . style . cursor = ''
47- document . body . style . userSelect = ''
48- }
60+ startX . current = e . clientX
61+ startWidth . current = width
4962
5063 document . addEventListener ( 'mousemove' , onMouseMove )
5164 document . addEventListener ( 'mouseup' , onMouseUp )
5265 document . body . style . cursor = 'col-resize'
5366 document . body . style . userSelect = 'none'
5467 } ,
55- [ width ]
68+ [ width , onMouseMove , onMouseUp ]
5669 )
5770
5871 const handleKeyDown = useCallback (
0 commit comments