aboutsummaryrefslogtreecommitdiffstats
path: root/packages/excalidraw/components/TTDDialog/common.ts
diff options
context:
space:
mode:
authorkj_sh6042026-03-15 16:19:35 -0400
committerkj_sh6042026-03-15 16:19:35 -0400
commit6ec259a0e71174651bae95d4628138bf6fd68742 (patch)
tree5e33c6a5ec091ecabfcb257fdc7b6a88ed8754ac /packages/excalidraw/components/TTDDialog/common.ts
parent16c8578b15c727f22921f8a80a56ee4d4e7f2272 (diff)
refactor: packages/
Diffstat (limited to 'packages/excalidraw/components/TTDDialog/common.ts')
-rw-r--r--packages/excalidraw/components/TTDDialog/common.ts161
1 files changed, 161 insertions, 0 deletions
diff --git a/packages/excalidraw/components/TTDDialog/common.ts b/packages/excalidraw/components/TTDDialog/common.ts
new file mode 100644
index 0000000..4191126
--- /dev/null
+++ b/packages/excalidraw/components/TTDDialog/common.ts
@@ -0,0 +1,161 @@
+import type { MermaidConfig } from "@excalidraw/mermaid-to-excalidraw";
+import type { MermaidToExcalidrawResult } from "@excalidraw/mermaid-to-excalidraw/dist/interfaces";
+import { DEFAULT_EXPORT_PADDING, EDITOR_LS_KEYS } from "../../constants";
+import { convertToExcalidrawElements, exportToCanvas } from "../../index";
+import type { NonDeletedExcalidrawElement } from "../../element/types";
+import type { AppClassProperties, BinaryFiles } from "../../types";
+import { canvasToBlob } from "../../data/blob";
+import { EditorLocalStorage } from "../../data/EditorLocalStorage";
+import { t } from "../../i18n";
+
+const resetPreview = ({
+ canvasRef,
+ setError,
+}: {
+ canvasRef: React.RefObject<HTMLDivElement | null>;
+ setError: (error: Error | null) => void;
+}) => {
+ const canvasNode = canvasRef.current;
+
+ if (!canvasNode) {
+ return;
+ }
+ const parent = canvasNode.parentElement;
+ if (!parent) {
+ return;
+ }
+ parent.style.background = "";
+ setError(null);
+ canvasNode.replaceChildren();
+};
+
+export interface MermaidToExcalidrawLibProps {
+ loaded: boolean;
+ api: Promise<{
+ parseMermaidToExcalidraw: (
+ definition: string,
+ config?: MermaidConfig,
+ ) => Promise<MermaidToExcalidrawResult>;
+ }>;
+}
+
+interface ConvertMermaidToExcalidrawFormatProps {
+ canvasRef: React.RefObject<HTMLDivElement | null>;
+ mermaidToExcalidrawLib: MermaidToExcalidrawLibProps;
+ mermaidDefinition: string;
+ setError: (error: Error | null) => void;
+ data: React.MutableRefObject<{
+ elements: readonly NonDeletedExcalidrawElement[];
+ files: BinaryFiles | null;
+ }>;
+}
+
+export const convertMermaidToExcalidraw = async ({
+ canvasRef,
+ mermaidToExcalidrawLib,
+ mermaidDefinition,
+ setError,
+ data,
+}: ConvertMermaidToExcalidrawFormatProps) => {
+ const canvasNode = canvasRef.current;
+ const parent = canvasNode?.parentElement;
+
+ if (!canvasNode || !parent) {
+ return;
+ }
+
+ if (!mermaidDefinition) {
+ resetPreview({ canvasRef, setError });
+ return;
+ }
+
+ try {
+ const api = await mermaidToExcalidrawLib.api;
+
+ let ret;
+ try {
+ ret = await api.parseMermaidToExcalidraw(mermaidDefinition);
+ } catch (err: any) {
+ ret = await api.parseMermaidToExcalidraw(
+ mermaidDefinition.replace(/"/g, "'"),
+ );
+ }
+ const { elements, files } = ret;
+ setError(null);
+
+ data.current = {
+ elements: convertToExcalidrawElements(elements, {
+ regenerateIds: true,
+ }),
+ files,
+ };
+
+ const canvas = await exportToCanvas({
+ elements: data.current.elements,
+ files: data.current.files,
+ exportPadding: DEFAULT_EXPORT_PADDING,
+ maxWidthOrHeight:
+ Math.max(parent.offsetWidth, parent.offsetHeight) *
+ window.devicePixelRatio,
+ });
+ // if converting to blob fails, there's some problem that will
+ // likely prevent preview and export (e.g. canvas too big)
+ try {
+ await canvasToBlob(canvas);
+ } catch (e: any) {
+ if (e.name === "CANVAS_POSSIBLY_TOO_BIG") {
+ throw new Error(t("canvasError.canvasTooBig"));
+ }
+ throw e;
+ }
+ parent.style.background = "var(--default-bg-color)";
+ canvasNode.replaceChildren(canvas);
+ } catch (err: any) {
+ parent.style.background = "var(--default-bg-color)";
+ if (mermaidDefinition) {
+ setError(err);
+ }
+
+ throw err;
+ }
+};
+
+export const saveMermaidDataToStorage = (mermaidDefinition: string) => {
+ EditorLocalStorage.set(
+ EDITOR_LS_KEYS.MERMAID_TO_EXCALIDRAW,
+ mermaidDefinition,
+ );
+};
+
+export const insertToEditor = ({
+ app,
+ data,
+ text,
+ shouldSaveMermaidDataToStorage,
+}: {
+ app: AppClassProperties;
+ data: React.MutableRefObject<{
+ elements: readonly NonDeletedExcalidrawElement[];
+ files: BinaryFiles | null;
+ }>;
+ text?: string;
+ shouldSaveMermaidDataToStorage?: boolean;
+}) => {
+ const { elements: newElements, files } = data.current;
+
+ if (!newElements.length) {
+ return;
+ }
+
+ app.addElementsFromPasteOrLibrary({
+ elements: newElements,
+ files,
+ position: "center",
+ fitToContent: true,
+ });
+ app.setOpenDialog(null);
+
+ if (shouldSaveMermaidDataToStorage && text) {
+ saveMermaidDataToStorage(text);
+ }
+};