Closed tanmayaBiswalOdiware closed 1 year ago
Used React.createPortal to do the job.
This code shows the main component
import React, { useRef, useCallback } from "react";
import ReactDOM from "react-dom";
import { SimpleMdeReact } from "react-simplemde-editor";
import MathQuillContainer from "./MathQuillContainer";
import "easymde/dist/easymde.min.css";
import "./math.css";
const SimpleEditor = (props) => {
const [modalOpen, setModalOpen] = React.useState(false);
const editorRef = useRef();
const [value, setValue] = React.useState(
"Initial ***value*** $\\frac{10}{20}$ $$\\frac {a}{b}$$"
);
const onChange = React.useCallback((value) => {
setValue(value);
}, []);
const easyMde = useRef(null);
const getMdeInstanceCallback = useCallback((simpleMde) => {
easyMde.current = simpleMde;
}, []);
const Options = React.useMemo(() => {
return {
// autofocus: true,
spellChecker: false,
status: false,
placeholder: "Hold the door",
previewRender: (text) => {
// first process the markdown
const markdownHtml = easyMde.current.markdown(text);
// typeset with MathJax
const container = document.createElement("div");
container.innerHTML = markdownHtml;
props.mathJax.current.typesetClear([container]);
props.mathJax.current.typeset([container]);
return container.innerHTML;
},
toolbar: [
// usual toolbar options here like bold, italics etc,
// new toolbar option below
{
name: "formula-button",
title: "Math Expression",
action: (editor) => {
const cm = editor.codemirror;
editorRef.current = cm;
setModalOpen(true);
},
className: "fa fa-calculator"
}
]
// toolbar: false
};
}, []);
return (
<>
<SimpleMdeReact
value={value}
onChange={onChange}
options={Options}
getMdeInstance={getMdeInstanceCallback}
/>
{modalOpen && (
<MathQuillContainer onClose={setModalOpen} codemirror={editorRef} />
)}
</>
);
};
export default SimpleEditor;
The code below shows the portal component:
import React, { useRef, useState } from "react";
import ReactDOM from "react-dom";
import { addStyles, EditableMathField } from "react-mathquill";
addStyles();
function MathQuillContainer(props) {
const [latex, setLatex] = useState("\\frac{1}{\\sqrt{2}}\\cdot 2");
const mathRaw = useRef(null);
function insertIntoCM() {
let cm = props.codemirror.current;
// const text = cm.getSelection(); // You can also implement your reference picker here.
cm.replaceSelection("$" + latex + "$");
props.onClose(false);
}
function insertIntoCMBlock() {
let cm = props.codemirror.current;
cm.replaceSelection("$$" + latex + "$$");
props.onClose(false);
}
return ReactDOM.createPortal(
<div
style={{
position: "absolute", top: "0", bottom: "0", left: "0", right: "0", display: "grid", justifyContent: "center", alignItems: "center",
backgroundColor: "rgba(0,0,0,0.3)"
}}
onClick={(e) => {
e.stopPropagation();
props.onClose(false);
}}
>
<div
style={{ padding: 20, background: "#fff", borderRadius: "2px", display: "inline-block", minHeight: "300px", margin: "1rem",
position: "relative", minWidth: "300px", boxShadow: "0 3px 6px rgba(0,0,0,0.16), 0 3px 6px rgba(0,0,0,0.23)",
justifySelf: "center" }}
onClick={(e) => {
e.stopPropagation();
}}
>
<EditableMathField
latex={latex}
onChange={(mathField) => setLatex(mathField.latex())}
mathquillDidMount={(mathraw) => (mathRaw.current = mathraw.latex())}
/>
<hr />
<p>{latex}</p>
<button onClick={insertIntoCM}> Insert Inline </button>
<button onClick={insertIntoCMBlock}> Insert Block </button>
</div>
</div>,
document.querySelector("#modal-root-test")
);
}
export default MathQuillContainer;
The styles have not been finalized so it will look pretty rough, but you get the idea.
So I am trying to integrate MathQuill into EasyMDE and in my head I thought of a sleek way of allowing users to input Math by letting them type LaTeX inside a separate MathQuill component and then having an
insert
button to let the raw math be accepted and appended to thetextbox
of EasyMDE.So far, no success on my side. Is it possible to achieve this kind of functionality with custom toolbar?
Link to the CodeSandbox