From 3d40221dc1181d26da93003efd3039c3da4064bd Mon Sep 17 00:00:00 2001 From: Mark Tolmacs Date: Sun, 30 Mar 2025 16:32:47 +0200 Subject: [PATCH] Restore input value and fix history Signed-off-by: Mark Tolmacs --- .../excalidraw/components/Stats/Angle.tsx | 30 +++++++++---- .../excalidraw/components/Stats/DragInput.tsx | 43 +++++++++++-------- .../excalidraw/components/Stats/Position.tsx | 27 +++++++++--- packages/excalidraw/components/Stats/utils.ts | 21 ++++----- 4 files changed, 79 insertions(+), 42 deletions(-) diff --git a/packages/excalidraw/components/Stats/Angle.tsx b/packages/excalidraw/components/Stats/Angle.tsx index 3c0d59e661..301cf8b84f 100644 --- a/packages/excalidraw/components/Stats/Angle.tsx +++ b/packages/excalidraw/components/Stats/Angle.tsx @@ -117,6 +117,7 @@ const handleFinished: DragFinishedCallbackType = ({ scene, accumulatedChange, setAppState, + setInputValue, }) => { const elementsMap = scene.getNonDeletedElementsMap(); const origElement = originalElements[0]; @@ -125,19 +126,32 @@ const handleFinished: DragFinishedCallbackType = ({ const latestElement = elementsMap.get(origElement.id); if (latestElement) { - updateBindings(latestElement, elementsMap, originalAppState.zoom, () => { - const change = degreesToRadians(accumulatedChange as Degrees); - - mutateElement(latestElement, { - angle: (latestElement.angle - change) as Radians, - }); - }); - setAppState({ suggestedBindings: [], }); + + const success = updateBindings( + latestElement, + elementsMap, + originalAppState.zoom, + ); + + if (!success) { + const change = degreesToRadians(accumulatedChange as Degrees); + const angle = (latestElement.angle - change) as Radians; + + mutateElement(latestElement, { + angle, + }); + + setInputValue(angle); + + return false; + } } } + + return true; }; const Angle = ({ element, scene, appState, property }: AngleProps) => { diff --git a/packages/excalidraw/components/Stats/DragInput.tsx b/packages/excalidraw/components/Stats/DragInput.tsx index 7d741ecab3..65e8adaea5 100644 --- a/packages/excalidraw/components/Stats/DragInput.tsx +++ b/packages/excalidraw/components/Stats/DragInput.tsx @@ -48,7 +48,8 @@ export type DragFinishedCallbackType< originalAppState: AppState; accumulatedChange: number; setAppState: React.Component["setState"]; -}) => void; + setInputValue: (value: number) => void; +}) => boolean; interface StatsDragInputProps< T extends StatsInputProperty, @@ -155,7 +156,7 @@ const StatsDragInput = < setInputValue: (value) => setInputValue(String(value)), setAppState, }); - dragFinishedCallback?.({ + const commit = dragFinishedCallback?.({ originalElements: elements, originalElementsMap, scene, @@ -163,10 +164,13 @@ const StatsDragInput = < accumulatedChange: rounded, property, setAppState, + setInputValue: (value) => setInputValue(String(value)), }); - app.syncActionResult({ - captureUpdate: CaptureUpdateAction.IMMEDIATELY, - }); + if (commit) { + app.syncActionResult({ + captureUpdate: CaptureUpdateAction.IMMEDIATELY, + }); + } } }; @@ -311,21 +315,26 @@ const StatsDragInput = < false, ); + let commit = true; if (originalElements !== null && originalElementsMap !== null) { - dragFinishedCallback?.({ - originalElements, - originalElementsMap, - scene, - originalAppState, - property, - accumulatedChange, - setAppState, - }); + commit = + dragFinishedCallback?.({ + originalElements, + originalElementsMap, + scene, + originalAppState, + property, + accumulatedChange, + setAppState, + setInputValue: (value) => setInputValue(String(value)), + }) ?? true; } - app.syncActionResult({ - captureUpdate: CaptureUpdateAction.IMMEDIATELY, - }); + if (commit) { + app.syncActionResult({ + captureUpdate: CaptureUpdateAction.IMMEDIATELY, + }); + } lastPointer = null; accumulatedChange = 0; diff --git a/packages/excalidraw/components/Stats/Position.tsx b/packages/excalidraw/components/Stats/Position.tsx index 312e0eec95..ad6ff16b2c 100644 --- a/packages/excalidraw/components/Stats/Position.tsx +++ b/packages/excalidraw/components/Stats/Position.tsx @@ -204,7 +204,8 @@ const handleFinished: DragFinishedCallbackType<"x" | "y"> = ({ accumulatedChange, property, setAppState, -}) => { + setInputValue, +}): boolean => { const elementsMap = scene.getNonDeletedElementsMap(); const origElement = originalElements[0]; @@ -212,17 +213,29 @@ const handleFinished: DragFinishedCallbackType<"x" | "y"> = ({ const latestElement = elementsMap.get(origElement.id); if (latestElement) { - updateBindings(latestElement, elementsMap, originalAppState.zoom, () => { - mutateElement(latestElement, { - [property]: latestElement[property] - accumulatedChange, - }); - }); - setAppState({ suggestedBindings: [], }); + + const success = updateBindings( + latestElement, + elementsMap, + originalAppState.zoom, + ); + + if (!success) { + mutateElement(latestElement, { + [property]: latestElement[property] - accumulatedChange, + }); + + setInputValue(latestElement[property] - accumulatedChange); + } + + return false; } } + + return true; }; const Position = ({ property, element, scene, appState }: PositionProps) => { diff --git a/packages/excalidraw/components/Stats/utils.ts b/packages/excalidraw/components/Stats/utils.ts index 3281a760f5..bbba3df2bc 100644 --- a/packages/excalidraw/components/Stats/utils.ts +++ b/packages/excalidraw/components/Stats/utils.ts @@ -204,8 +204,7 @@ export const updateBindings = ( latestElement: ExcalidrawElement, elementsMap: NonDeletedSceneElementsMap, zoom?: AppState["zoom"], - bindingElementKeptOriginalBinding?: () => void, -) => { +): boolean => { if (isBindingElement(latestElement)) { const [start, end] = getOriginalBindingsIfStillCloseToArrowEnds( latestElement, @@ -217,15 +216,17 @@ export const updateBindings = ( (latestElement.startBinding && start) || (latestElement.endBinding && end) ) { - bindingElementKeptOriginalBinding?.(); - } else { - if (latestElement.startBinding && !start) { - unbindLinearElement(latestElement, "start"); - } + return false; + } - if (latestElement.endBinding && !end) { - unbindLinearElement(latestElement, "end"); - } + if (latestElement.startBinding && !start) { + unbindLinearElement(latestElement, "start"); + } + + if (latestElement.endBinding && !end) { + unbindLinearElement(latestElement, "end"); } } + + return true; };