diff --git a/packages/element/src/mutateElement.ts b/packages/element/src/mutateElement.ts index d87007369..4e4bc60f6 100644 --- a/packages/element/src/mutateElement.ts +++ b/packages/element/src/mutateElement.ts @@ -38,6 +38,7 @@ export const mutateElement = >( // If true, the elbow arrow tries to bind to the nearest element. If false // it tries to keep the same bound element, if any. isDragging?: boolean; + propertiesToDrop?: string[]; }, ): TElement => { let didChange = false; @@ -128,6 +129,12 @@ export const mutateElement = >( } } + if (options?.propertiesToDrop?.includes(key)) { + delete (element as any)[key]; + didChange = true; + continue; + } + (element as any)[key] = value; didChange = true; } diff --git a/packages/excalidraw/components/ShapeSwitch.tsx b/packages/excalidraw/components/ShapeSwitch.tsx index 5ba4c45b5..e1cd1ffe0 100644 --- a/packages/excalidraw/components/ShapeSwitch.tsx +++ b/packages/excalidraw/components/ShapeSwitch.tsx @@ -35,6 +35,7 @@ import { LinearElementEditor } from "@excalidraw/element/linearElementEditor"; import type { ElementsMap, + ExcalidrawArrowElement, ExcalidrawElement, ExcalidrawLinearElement, ExcalidrawTextContainer, @@ -432,15 +433,48 @@ export const switchShapes = ( selectedLinearSwitchableElements.forEach((element) => { ShapeCache.delete(element); - mutateElement( - element as ExcalidrawLinearElement, - { - type: nextType as LinearSwitchableToolType, - startArrowhead: null, - endArrowhead: nextType === "arrow" ? "arrow" : null, - }, - false, - ); + // TODO: maybe add a separate function for safe type conversion + // without overloading mutateElement + if (nextType === "arrow") { + mutateElement( + element as ExcalidrawArrowElement, + { + type: "arrow", + startArrowhead: app.state.currentItemStartArrowhead, + endArrowhead: app.state.currentItemEndArrowhead, + startBinding: null, + endBinding: null, + ...(app.state.currentItemArrowType === "elbow" + ? { elbowed: true } + : {}), + }, + false, + ); + } + + if (nextType === "line") { + if (isElbowArrow(element)) { + mutateElement( + element as ExcalidrawLinearElement, + { + type: "line", + startArrowhead: null, + endArrowhead: null, + startBinding: null, + endBinding: null, + }, + false, + { + propertiesToDrop: [ + "elbowed", + "startIsSpecial", + "endIsSpecial", + "fixedSegments", + ], + }, + ); + } + } if (isElbowArrow(element)) { const nextPoints = convertLineToElbow(element);