Path: blob/master/src/packages/frontend/editors/slate/elements/code-block/mermaid.tsx
1698 views
/*1* This file is part of CoCalc: Copyright © 2020 Sagemath, Inc.2* License: MS-RSL – see LICENSE.md for details3*/45import { useEffect, useRef, useState } from "react";6import ShowError from "@cocalc/frontend/components/error";7import { delay } from "awaiting";8import { uuid, replace_all } from "@cocalc/util/misc";9import { useFileContext } from "@cocalc/frontend/lib/file-context";1011interface Props {12value: string;13style?;14}1516export default function Mermaid({ value, style }: Props) {17const mermaidRef = useRef<any>(null);18const [mermaidError, setMermaidError] = useState<string>("");19const processingRef = useRef<boolean>(false);20const [id] = useState<string>("a" + replace_all(uuid(), "-", ""));21const { getMermaid } = useFileContext();2223if (getMermaid == null) {24return <div style={style}>Mermaid not available</div>;25}2627const waitUntilNotProcessing = async () => {28let d = 1;29while (processingRef.current) {30// value changed *while* processing.31await delay(d);32d *= 1.2;33}34};3536useEffect(() => {37const elt = mermaidRef.current;38if (!elt) {39return;40}41if (!value.trim()) {42elt.innerHTML = "";43return;44}45(async () => {46try {47await waitUntilNotProcessing();48processingRef.current = true;49setMermaidError("");50const mermaid = await getMermaid();51const { svg } = await mermaid.render(id, value);52elt.innerHTML = svg;53} catch (err) {54setMermaidError(err.str ?? `${err}`);55} finally {56processingRef.current = false;57}58})();59}, [value]);6061return (62<div style={style}>63<pre ref={mermaidRef}></pre>64<ShowError error={mermaidError} setError={setMermaidError} />65</div>66);67}686970