From d76bc7890daddde3c082c06d2bd061be4af8caf4 Mon Sep 17 00:00:00 2001 From: Aakansha Doshi Date: Mon, 12 Jun 2023 11:53:10 +0530 Subject: [PATCH] make type optional when id present --- src/data/transform.ts | 155 +++++++++++++++--------- src/data/types.ts | 80 ++++++++---- src/packages/excalidraw/example/App.tsx | 2 +- 3 files changed, 157 insertions(+), 80 deletions(-) diff --git a/src/data/transform.ts b/src/data/transform.ts index 5502be7bed..f78b368a45 100644 --- a/src/data/transform.ts +++ b/src/data/transform.ts @@ -25,6 +25,7 @@ import { ExcalidrawBindableElement, ExcalidrawElement, ExcalidrawGenericElement, + ExcalidrawImageElement, ExcalidrawLinearElement, ExcalidrawTextElement, } from "../element/types"; @@ -132,72 +133,116 @@ const bindLinearElementToElement = ( if (start) { const width = start?.width ?? DEFAULT_DIMENSION; const height = start?.height ?? DEFAULT_DIMENSION; - const existingElement = start.id - ? excalidrawElements.get().find((ele) => ele?.id === start.id) - : undefined; - const startX = start.x || excliadrawLinearElement.x - width; - const startY = start.y || excliadrawLinearElement.y - height / 2; - - if (start.type === "text") { - startBoundElement = newTextElement({ - x: startX, - y: startY, - ...existingElement, - ...start, - }); - // to position the text correctly when coordinates not provided - mutateElement(startBoundElement, { - x: start.x || excliadrawLinearElement.x - startBoundElement.width, - y: start.y || excliadrawLinearElement.y - startBoundElement.height / 2, - }); - } else { - startBoundElement = newElement({ - x: startX, - y: startY, - width, - height, - ...existingElement, - ...start, - }); + let existingElement; + if (start.id) { + existingElement = excalidrawElements + .get() + .find((ele) => ele?.id === start.id) as Exclude< + ExcalidrawBindableElement, + ExcalidrawImageElement + >; + if (!existingElement) { + console.error(`No element for start binding with id ${start.id} found`); + } } - bindLinearElement( - excliadrawLinearElement, - startBoundElement as ExcalidrawBindableElement, - "start", - ); + const startX = start.x || excliadrawLinearElement.x - width; + const startY = start.y || excliadrawLinearElement.y - height / 2; + const startType = existingElement ? existingElement.type : start.type; + + if (startType) { + if (startType === "text") { + let text = ""; + if (existingElement && existingElement.type === "text") { + text = existingElement.text; + } else if (start.type === "text") { + text = start.text; + } + startBoundElement = newTextElement({ + x: startX, + y: startY, + type: "text", + ...existingElement, + ...start, + text, + }); + // to position the text correctly when coordinates not provided + mutateElement(startBoundElement, { + x: start.x || excliadrawLinearElement.x - startBoundElement.width, + y: + start.y || excliadrawLinearElement.y - startBoundElement.height / 2, + }); + } else { + startBoundElement = newElement({ + x: startX, + y: startY, + width, + height, + ...existingElement, + ...start, + type: startType, + }); + } + + bindLinearElement( + excliadrawLinearElement, + startBoundElement as ExcalidrawBindableElement, + "start", + ); + } } if (end) { const height = end?.height ?? DEFAULT_DIMENSION; const width = end?.width ?? DEFAULT_DIMENSION; - const existingElement = end.id - ? excalidrawElements.get().find((ele) => ele?.id === end.id) - : undefined; + let existingElement; + if (end.id) { + existingElement = excalidrawElements + .get() + .find((ele) => ele?.id === end.id) as Exclude< + ExcalidrawBindableElement, + ExcalidrawImageElement + >; + if (!existingElement) { + console.error(`No element for end binding with id ${end.id} found`); + } + } const endX = end.x || excliadrawLinearElement.x + excliadrawLinearElement.width; const endY = end.y || excliadrawLinearElement.y - height / 2; + const endType = existingElement ? existingElement.type : end.type; - if (end.type === "text") { - endBoundElement = newTextElement({ - x: endX, - y: endY, - ...existingElement, - ...end, - }); - // to position the text correctly when coordinates not provided - mutateElement(endBoundElement, { - y: end.y || excliadrawLinearElement.y - endBoundElement.height / 2, - }); - } else { - endBoundElement = newElement({ - x: endX, - y: endY, - width, - height, - ...existingElement, - ...end, - }) as ExcalidrawBindableElement; + if (endType) { + if (endType === "text") { + let text = ""; + if (existingElement && existingElement.type === "text") { + text = existingElement.text; + } else if (end.type === "text") { + text = end.text; + } + endBoundElement = newTextElement({ + x: endX, + y: endY, + type: "text", + ...existingElement, + ...end, + text, + }); + // to position the text correctly when coordinates not provided + mutateElement(endBoundElement, { + y: end.y || excliadrawLinearElement.y - endBoundElement.height / 2, + }); + } else { + endBoundElement = newElement({ + x: endX, + y: endY, + width, + height, + ...existingElement, + ...end, + type: endType, + }) as ExcalidrawBindableElement; + } } bindLinearElement( excliadrawLinearElement, diff --git a/src/data/types.ts b/src/data/types.ts index 09540b444d..c154af6252 100644 --- a/src/data/types.ts +++ b/src/data/types.ts @@ -56,34 +56,66 @@ export type ValidLinearElement = { } & MarkOptional; end?: | ( - | { - type: Exclude< - ExcalidrawBindableElement["type"], - "image" | "selection" | "text" - >; - id?: ExcalidrawGenericElement["id"]; - } - | ({ - type: "text"; - text: string; - id?: ExcalidrawTextElement["id"]; - } & Partial) + | ( + | { + type: Exclude< + ExcalidrawBindableElement["type"], + "image" | "selection" | "text" + >; + id?: ExcalidrawGenericElement["id"]; + } + | { + id: ExcalidrawGenericElement["id"]; + type?: Exclude< + ExcalidrawBindableElement["type"], + "image" | "selection" | "text" + >; + } + ) + | (( + | { + type: "text"; + text: string; + } + | { + type?: "text"; + id: ExcalidrawTextElement["id"]; + text: string; + } + ) & + Partial) ) & MarkOptional; start?: | ( - | { - type: Exclude< - ExcalidrawBindableElement["type"], - "image" | "selection" | "text" - >; - id?: ExcalidrawGenericElement["id"]; - } - | ({ - type: "text"; - text: string; - id?: ExcalidrawTextElement["id"]; - } & Partial) + | ( + | { + type: Exclude< + ExcalidrawBindableElement["type"], + "image" | "selection" | "text" + >; + id?: ExcalidrawGenericElement["id"]; + } + | { + id: ExcalidrawGenericElement["id"]; + type?: Exclude< + ExcalidrawBindableElement["type"], + "image" | "selection" | "text" + >; + } + ) + | (( + | { + type: "text"; + text: string; + } + | { + type?: "text"; + id: ExcalidrawTextElement["id"]; + text: string; + } + ) & + Partial) ) & MarkOptional; } & Partial; diff --git a/src/packages/excalidraw/example/App.tsx b/src/packages/excalidraw/example/App.tsx index cac11a0cc4..8a36da6ab9 100644 --- a/src/packages/excalidraw/example/App.tsx +++ b/src/packages/excalidraw/example/App.tsx @@ -208,7 +208,7 @@ export default function App({ appTitle, useCustom, customArgs }: AppProps) { type: "arrow", x: 300, y: 150, - start: { type: "rectangle", id: "rect-1" }, + start: { id: "rect-1" }, end: { type: "ellipse" }, }, {