From 6ec259a0e71174651bae95d4628138bf6fd68742 Mon Sep 17 00:00:00 2001 From: kj_sh604 Date: Sun, 15 Mar 2026 16:19:35 -0400 Subject: refactor: packages/ --- .../components/TTDDialog/MermaidToExcalidraw.tsx | 132 +++++++++++++++++++++ 1 file changed, 132 insertions(+) create mode 100644 packages/excalidraw/components/TTDDialog/MermaidToExcalidraw.tsx (limited to 'packages/excalidraw/components/TTDDialog/MermaidToExcalidraw.tsx') diff --git a/packages/excalidraw/components/TTDDialog/MermaidToExcalidraw.tsx b/packages/excalidraw/components/TTDDialog/MermaidToExcalidraw.tsx new file mode 100644 index 0000000..83fb91d --- /dev/null +++ b/packages/excalidraw/components/TTDDialog/MermaidToExcalidraw.tsx @@ -0,0 +1,132 @@ +import { useState, useRef, useEffect, useDeferredValue } from "react"; +import type { BinaryFiles } from "../../types"; +import { useApp } from "../App"; +import type { NonDeletedExcalidrawElement } from "../../element/types"; +import { ArrowRightIcon } from "../icons"; +import "./MermaidToExcalidraw.scss"; +import { t } from "../../i18n"; +import Trans from "../Trans"; +import type { MermaidToExcalidrawLibProps } from "./common"; +import { + convertMermaidToExcalidraw, + insertToEditor, + saveMermaidDataToStorage, +} from "./common"; +import { TTDDialogPanels } from "./TTDDialogPanels"; +import { TTDDialogPanel } from "./TTDDialogPanel"; +import { TTDDialogInput } from "./TTDDialogInput"; +import { TTDDialogOutput } from "./TTDDialogOutput"; +import { EditorLocalStorage } from "../../data/EditorLocalStorage"; +import { EDITOR_LS_KEYS } from "../../constants"; +import { debounce, isDevEnv } from "../../utils"; +import { TTDDialogSubmitShortcut } from "./TTDDialogSubmitShortcut"; + +const MERMAID_EXAMPLE = + "flowchart TD\n A[Christmas] -->|Get money| B(Go shopping)\n B --> C{Let me think}\n C -->|One| D[Laptop]\n C -->|Two| E[iPhone]\n C -->|Three| F[Car]"; + +const debouncedSaveMermaidDefinition = debounce(saveMermaidDataToStorage, 300); + +const MermaidToExcalidraw = ({ + mermaidToExcalidrawLib, +}: { + mermaidToExcalidrawLib: MermaidToExcalidrawLibProps; +}) => { + const [text, setText] = useState( + () => + EditorLocalStorage.get(EDITOR_LS_KEYS.MERMAID_TO_EXCALIDRAW) || + MERMAID_EXAMPLE, + ); + const deferredText = useDeferredValue(text.trim()); + const [error, setError] = useState(null); + + const canvasRef = useRef(null); + const data = useRef<{ + elements: readonly NonDeletedExcalidrawElement[]; + files: BinaryFiles | null; + }>({ elements: [], files: null }); + + const app = useApp(); + + useEffect(() => { + convertMermaidToExcalidraw({ + canvasRef, + data, + mermaidToExcalidrawLib, + setError, + mermaidDefinition: deferredText, + }).catch((err) => { + if (isDevEnv()) { + console.error("Failed to parse mermaid definition", err); + } + }); + + debouncedSaveMermaidDefinition(deferredText); + }, [deferredText, mermaidToExcalidrawLib]); + + useEffect( + () => () => { + debouncedSaveMermaidDefinition.flush(); + }, + [], + ); + + const onInsertToEditor = () => { + insertToEditor({ + app, + data, + text, + shouldSaveMermaidDataToStorage: true, + }); + }; + + return ( + <> +
+ ( + {el} + )} + sequenceLink={(el) => ( + + {el} + + )} + classLink={(el) => ( + {el} + )} + /> +
+ + + setText(event.target.value)} + onKeyboardSubmit={() => { + onInsertToEditor(); + }} + /> + + { + onInsertToEditor(); + }, + label: t("mermaid.button"), + icon: ArrowRightIcon, + }} + renderSubmitShortcut={() => } + > + + + + + ); +}; +export default MermaidToExcalidraw; -- cgit v1.2.3