react-md-editor
react-md-editor copied to clipboard
About Custom Toolbar
Hello everyone I am a beginner to React. I am trying to modifiy the add image command. I want a Modal to appear on screen when I click the command, so that I can use the modal to upload the image to a server, then insert the url to the editor, as is shown below:

But I don't know what's the proper way to achieve this goal. Currently I use a parent component to manage an Editor and a Modal:
import * as React from "react";
import MDEditor from "@uiw/react-md-editor";
import UploadModal from "./UploadModal";
export default function Markdown() {
const [api, setApi] = React.useState(null);
const [showModal, setShowModal] = React.useState(false);
let EditorRef = React.createRef();
const img = {
name: "img",
keyCommand: "img",
buttonProps: { "aria-label": "Insert img" },
icon: (
<svg width="12" height="12" viewBox="0 0 520 520">
<path
fill="currentColor"
d="M15.7083333,468 C7.03242448,468 0,462.030833 0,454.666667 L0,421.333333 C0,413.969167 7.03242448,408 15.7083333,408 L361.291667,408 C369.967576,408 377,413.969167 377,421.333333 L377,454.666667 C377,462.030833 369.967576,468 361.291667,468 L15.7083333,468 Z M21.6666667,366 C9.69989583,366 0,359.831861 0,352.222222 L0,317.777778 C0,310.168139 9.69989583,304 21.6666667,304 L498.333333,304 C510.300104,304 520,310.168139 520,317.777778 L520,352.222222 C520,359.831861 510.300104,366 498.333333,366 L21.6666667,366 Z M136.835938,64 L136.835937,126 L107.25,126 L107.25,251 L40.75,251 L40.75,126 L-5.68434189e-14,126 L-5.68434189e-14,64 L136.835938,64 Z M212,64 L212,251 L161.648438,251 L161.648438,64 L212,64 Z M378,64 L378,126 L343.25,126 L343.25,251 L281.75,251 L281.75,126 L238,126 L238,64 L378,64 Z M449.047619,189.550781 L520,189.550781 L520,251 L405,251 L405,64 L449.047619,64 L449.047619,189.550781 Z"
/>
</svg>
),
execute: (state, api) => {
setShowModal(true);
setApi(api);
},
};
const [value, setValue] = React.useState(
"Hello Markdown! `Tab` key uses default behavior"
);
return (
<div className="container">
<MDEditor
ref={EditorRef}
value={value}
onChange={setValue}
commands={[
// Custom Toolbars
img,
]}
/>
{showModal ? (
<UploadModal
onSubmit={(url) => {
api.replaceSelection(``);
}}
onExit={() => {
setShowModal(false);
}}
/>
) : null}
</div>
);
}
Here is the modal component:
import * as React from "react";
import Upload from "rc-upload";
import { Button, Image, Modal, ProgressBar } from "react-bootstrap";
export default function UploadModal(props) {
const [showUploader, setShowUploader] = React.useState(true);
const [showImage, setShowImage] = React.useState(false);
const [showProcess, setShowProcess] = React.useState(false);
const [process, setProcess] = React.useState(0);
const [url, setUrl] = React.useState(null);
const handleClose = () => {
setShowUploader(true);
setShowImage(false);
setUrl(null);
setProcess(0);
setShowProcess(false);
props.onExit();
};
const handleSubmit = () => {
handleClose();
props.onSubmit(url);
};
const uploaderProps = {
action: "/upload",
multiple: true,
beforeUpload(file) {},
onStart: (file) => {
setShowProcess(true);
},
onSuccess(result) {
setUrl(result.url);
setShowImage(true);
setShowUploader(false);
setShowProcess(false);
},
onProgress(step) {
setProcess(step.percent);
},
onError(err) {
console.log("onError", err);
},
};
return (
<Modal show={true} onHide={handleClose}>
<Modal.Header closeButton>
<Modal.Title>Upload Image</Modal.Title>
</Modal.Header>
<Modal.Body className="d-flex justify-content-center">
{showUploader ? (
<Upload
{...uploaderProps}
className={
"w-100 border border-3 border-secondary rounded bg-light"
}
component={"div"}
>
<br />
<br />
<p className="text-secondary text-center">
Click or drag the image here to upload.
</p>
<br />
<br />
</Upload>
) : null}
{showImage ? (
<Image src={url} thumbnail="true" className="w-50" />
) : null}
{showProcess ? <ProgressBar now={process} /> : null}
</Modal.Body>
<Modal.Footer>
<Button variant="secondary" onClick={handleClose}>
Close
</Button>
<Button variant="primary" onClick={handleSubmit}>
OK
</Button>
</Modal.Footer>
</Modal>
);
}
These code can achieve exactly what I want. But I think they are very bad. It seems that the parent component needs to get the api of the editor, and I don't know how to do it.
Does anyone know how to do it properly?