From b459e5cfd2ebc783a62a77ca719b0ef329c4457b Mon Sep 17 00:00:00 2001 From: zsviczian Date: Mon, 26 Aug 2024 15:58:46 +0200 Subject: [PATCH] fix: context menu does not work after after dragging on StatsDragInput (#8386) Co-authored-by: dwelle <5153846+dwelle@users.noreply.github.com> --- .../excalidraw/components/Stats/DragInput.tsx | 72 ++++++++++++------- 1 file changed, 48 insertions(+), 24 deletions(-) diff --git a/packages/excalidraw/components/Stats/DragInput.tsx b/packages/excalidraw/components/Stats/DragInput.tsx index d7120bdef..77cc942cf 100644 --- a/packages/excalidraw/components/Stats/DragInput.tsx +++ b/packages/excalidraw/components/Stats/DragInput.tsx @@ -136,22 +136,43 @@ const StatsDragInput = < } }; - const handleInputValueRef = useRef(handleInputValue); - handleInputValueRef.current = handleInputValue; + const callbacksRef = useRef< + Partial<{ + handleInputValue: typeof handleInputValue; + onPointerUp: (event: PointerEvent) => void; + onPointerMove: (event: PointerEvent) => void; + }> + >({}); + callbacksRef.current.handleInputValue = handleInputValue; // make sure that clicking on canvas (which umounts the component) // updates current input value (blur isn't triggered) useEffect(() => { const input = inputRef.current; + const callbacks = callbacksRef.current; return () => { const nextValue = input?.value; if (nextValue) { - handleInputValueRef.current( + callbacks.handleInputValue?.( nextValue, stateRef.current.originalElements, stateRef.current.originalAppState, ); } + + // generally not needed, but in case `pointerup` doesn't fire and + // we don't remove the listeners that way, we should at least remove + // on unmount + window.removeEventListener( + EVENT.POINTER_MOVE, + callbacks.onPointerMove!, + false, + ); + window.removeEventListener( + EVENT.POINTER_UP, + callbacks.onPointerUp!, + false, + ); }; }, [ // we need to track change of `editable` state as mount/unmount @@ -248,28 +269,31 @@ const StatsDragInput = < }; }; + const onPointerUp = () => { + window.removeEventListener( + EVENT.POINTER_MOVE, + onPointerMove, + false, + ); + + app.syncActionResult({ storeAction: StoreAction.CAPTURE }); + + lastPointer = null; + accumulatedChange = 0; + stepChange = 0; + originalElements = null; + originalElementsMap = null; + + document.body.classList.remove("excalidraw-cursor-resize"); + + window.removeEventListener(EVENT.POINTER_UP, onPointerUp, false); + }; + + callbacksRef.current.onPointerMove = onPointerMove; + callbacksRef.current.onPointerUp = onPointerUp; + window.addEventListener(EVENT.POINTER_MOVE, onPointerMove, false); - window.addEventListener( - EVENT.POINTER_UP, - () => { - window.removeEventListener( - EVENT.POINTER_MOVE, - onPointerMove, - false, - ); - - app.syncActionResult({ storeAction: StoreAction.CAPTURE }); - - lastPointer = null; - accumulatedChange = 0; - stepChange = 0; - originalElements = null; - originalElementsMap = null; - - document.body.classList.remove("excalidraw-cursor-resize"); - }, - false, - ); + window.addEventListener(EVENT.POINTER_UP, onPointerUp, false); } }} onPointerEnter={() => {