uiwjs / react-md-editor

A simple markdown editor with preview, implemented with React.js and TypeScript.
https://uiwjs.github.io/react-md-editor
MIT License
2.04k stars 149 forks source link

How to set previewOptions in MDEditor.Markdown? #550

Closed jimkk159 closed 1 year ago

jimkk159 commented 1 year ago

Hello, I am using the KaTeX & mermaid Plugins in <MDEditor/> just like example, everything goes fine.

<MDEditor
  source={markdown}
  previewOptions={{
    components: {
      code: Code,
    },
  }}
/>

34

However, when I use the MDEditor.Markdown to see the result of the editted code.

It becomes to the orgin code style

<MDEditor.Markdown
  source={post.content}
  previewOptions={{
    components: {
      code: Code,
    },
  }}
/>

like

flowchart LR
    subgraph global
        direction LR
        this-->global_Object
        subgraph global_Object
            direction LR
                global.count
        end
        subgraph test
            direction LR
            this
            count-->0
        end
    end

Does I miss something?

Is the Markdown rewirte components property in \ not same as the \?

My version is "@uiw/react-md-editor": "^3.23.0",

jaywcjlove commented 1 year ago

@jimkk159 https://codesandbox.io/embed/priceless-monad-9ztv5p?fontsize=14&hidenavigation=1&theme=dark

import React, { useState, useRef, useEffect, useCallback } from "react";
import ReactDOM from "react-dom";
import MDEditor from "@uiw/react-md-editor";
import mermaid from "mermaid";

const mdMermaid = `The following are some examples of the diagrams, charts and graphs that can be made using Mermaid and the Markdown-inspired text specific to it. 

\`\`\`mermaid
graph TD
A[Hard] -->|Text| B(Round)
B --> C{Decision}
C -->|One| D[Result 1]
C -->|Two| E[Result 2]
\`\`\`

\`\`\`mermaid
sequenceDiagram
Alice->>John: Hello John, how are you?
loop Healthcheck
    John->>John: Fight against hypochondria
end
Note right of John: Rational thoughts!
John-->>Alice: Great!
John->>Bob: How about you?
Bob-->>John: Jolly good!
\`\`\`
`;

const randomid = () => parseInt(String(Math.random() * 1e15), 10).toString(36);

const Code = ({ inline, children = [], className, ...props }) => {
  const demoid = useRef(`dome${randomid()}`);
  const code = getCode(children);
  const demo = useRef(null);
  const handle = useCallback(async () => {
    if (demo.current) {
      try {
        const { svg } = await mermaid.render(demoid.current, code);
        demo.current.innerHTML = svg;
      } catch (error) {
        demo.current.innerHTML = error;
      }
    }
  }, [demo, code]);

  useEffect(() => handle(), [handle]);

  if (
    typeof code === "string" &&
    typeof className === "string" &&
    /^language-mermaid/.test(className.toLocaleLowerCase())
  ) {
    return (
      <code ref={demo}>
        <code id={demoid.current} style={{ display: "none" }} />
      </code>
    );
  }
  return <code className={String(className)}>{children}</code>;
};

const getCode = (arr = []) =>
  arr
    .map((dt) => {
      if (typeof dt === "string") {
        return dt;
      }
      if (dt.props && dt.props.children) {
        return getCode(dt.props.children);
      }
      return false;
    })
    .filter(Boolean)
    .join("");

export default function App() {
  const [value, setValue] = useState(mdMermaid);
  return (
    <React.Fragment>
      <div data-color-mode="dart">
        <MDEditor
          onChange={(newValue = "") => setValue(newValue)}
          textareaProps={{
            placeholder: "Please enter Markdown text"
          }}
          height={500}
          value={value}
          previewOptions={{
            components: {
              code: Code
            }
          }}
        />
      </div>

      <div data-color-mode="light">
        <MDEditor
          onChange={(newValue = "") => setValue(newValue)}
          textareaProps={{
            placeholder: "Please enter Markdown text"
          }}
          height={500}
          value={value}
          previewOptions={{
            components: {
              code: Code
            }
          }}
        />
      </div>

      <div data-color-mode="light">
        <MDEditor.Markdown
          components={{
            code: Code
          }}
          source={value}
        />
      </div>

      <div data-color-mode="dart">
        <MDEditor.Markdown
          components={{
            code: Code
          }}
          source={value}
        />
      </div>
    </React.Fragment>
  );
}
jimkk159 commented 1 year ago

Thanks, Does this mean that all the property in previewOptions will direct inject into the <MDEditor.Markdown />?