A simple markdown editor with preview, implemented with React.js and TypeScript. This React Component aims to provide a simple Markdown editor with syntax highlighting support. This is based on `textarea` encapsulation, so it does not depend on any modern code editors such as Acs, CodeMirror, Monaco etc.
### Features
- 📑 Indent line or selected text by pressing tab key, with customizable indentation.
- ♻️ Based on `textarea` encapsulation, does not depend on any modern code editors.
- 🚧 Does not depend on the [`uiw`](https://github.com/uiwjs/uiw) component library.
- 🚘 Automatic list on new lines.
- 😻 GitHub flavored markdown support.
- 🌒 Support dark-mode/night-mode **@v3.11.0+**.
- 💡 Support [next.js](https://github.com/uiwjs/react-md-editor/issues/52#issuecomment-848969341), [Use examples](#support-nextjs) in [next.js](https://nextjs.org/).
### Quick Start
```bash
npm i @uiw/react-md-editor
```
### Using
[](https://codesandbox.io/embed/markdown-editor-for-react-izdd6?fontsize=14&hidenavigation=1&theme=dark)
[](https://uiwjs.github.io/react-md-editor/)
[](https://uiw.gitee.io/react-md-editor/)
```jsx mdx:preview
import React from "react";
import MDEditor from '@uiw/react-md-editor';
export default function App() {
const [value, setValue] = React.useState("**Hello world!!!**");
return (
);
}
```
### Special Markdown syntax
**Supports for CSS Style**
Use HTML comments `` to let Markdown support style customization.
```markdown
## Title
Markdown Supports **Style**
```
**Ignore content display via HTML comments**
Shown in GitHub readme, excluded in HTML.
```markdown
# Hello World
Hello World
Good!
```
Output:
```html
Hello World
Good!
```
### Security
Please note markdown needs to be sanitized if you do not **completely trust** your authors.
Otherwise, your app is vulnerable to XSS. This can be achieved by adding [rehype-sanitize](https://github.com/rehypejs/rehype-sanitize) as a plugin.
```jsx mdx:preview
import React from "react";
import MDEditor from '@uiw/react-md-editor';
import rehypeSanitize from "rehype-sanitize";
export default function App() {
const [value, setValue] = React.useState(`**Hello world!!!** `);
return (
);
}
```
### Support Custom Mermaid Preview
Using [mermaid](https://github.com/mermaid-js/mermaid) to generation of diagram and flowchart from text in a similar manner as markdown
[](https://codesandbox.io/embed/recursing-water-08i59s?fontsize=14&hidenavigation=1&theme=dark)
```bash
npm install mermaid
```
```jsx mdx:preview
import React, { useState, useRef, useEffect } 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);
useEffect(() => {
if (demo.current) {
try {
const str = mermaid.render(demoid.current, code, () => null, demo.current);
// @ts-ignore
demo.current.innerHTML = str;
} catch (error) {
// @ts-ignore
demo.current.innerHTML = error;
}
}
}, [code, demo]);
if (
typeof code === "string" && typeof className === "string" &&
/^language-mermaid/.test(className.toLocaleLowerCase())
) {
return (
);
}
return {children};
};
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 (
setValue(newValue)}
textareaProps={{
placeholder: "Please enter Markdown text"
}}
height={500}
value={value}
previewOptions={{
components: {
code: Code
}
}}
/>
);
}
```
### Support Nextjs
Use examples in [nextjs](https://nextjs.org/). [`#52`](https://github.com/uiwjs/react-md-editor/issues/52#issuecomment-848969341) [`#224`](https://github.com/uiwjs/react-md-editor/issues/224#issuecomment-901112079)
[](https://codesandbox.io/embed/nextjs-example-react-md-editor-qjhn7?fontsize=14&hidenavigation=1&theme=dark) [](https://stackblitz.com/edit/nextjs-react-md-editor?embed=1&file=pages/index.js&hideExplorer=1&hideNavigation=1&theme=dark)
[](https://github.com/uiwjs/react-md-editor/issues/52#issuecomment-848969341)
[](https://github.com/uiwjs/react-md-editor/issues/224#issuecomment-901112079)
```bash
npm install next-remove-imports
npm install @uiw/react-md-editor@v3.6.0
```
```js
// next.config.js
const removeImports = require('next-remove-imports')();
module.exports = removeImports({});
```
```jsx
import "@uiw/react-md-editor/markdown-editor.css";
import "@uiw/react-markdown-preview/markdown.css";
import dynamic from "next/dynamic";
import { useState } from "react";
const MDEditor = dynamic(
() => import("@uiw/react-md-editor"),
{ ssr: false }
);
function HomePage() {
const [value, setValue] = useState("**Hello world!!!**");
return (
);
}
export default HomePage;
```
### Support dark-mode/night-mode
By default, the [`dark-mode`](https://github.com/jaywcjlove/dark-mode/) is automatically switched according to the system. If you need to switch manually, just set the `data-color-mode="dark"` parameter for body.
```html
```
```js
document.documentElement.setAttribute('data-color-mode', 'dark')
document.documentElement.setAttribute('data-color-mode', 'light')
```
Inherit custom color variables by adding [`.wmde-markdown-var`](https://github.com/uiwjs/react-markdown-preview/blob/a53be1e93fb1c2327649c4a6b084adb80679affa/src/styles/markdown.less#L1-L193) selector. Setting theme styles with `data-color-mode="light"`.
```html
```
### Props
- `value: string`: The Markdown value.
- `onChange?: (value?: string, event?: React.ChangeEvent, state?: ContextStore)`: Event handler for the `onChange` event.
- `onHeightChange?: ((value?: CSSProperties['height'], oldValue?: CSSProperties['height'], state?: ContextStore)`: editor height change listener.
- `commands?: ICommand[]`: An array of [`ICommand`](https://github.com/uiwjs/react-md-editor/blob/d02543050c9abd8f7c72ae02b6421ac2e6ae421a/src/commands/index.ts#L39-L57), which, each one, contain a [`commands`](https://github.com/uiwjs/react-md-editor/blob/d02543050c9abd8f7c72ae02b6421ac2e6ae421a/src/commands/index.ts#L155-L180) property. If no commands are specified, the default will be used. Commands are explained in more details below.
- `commandsFilter?: (command: ICommand, isExtra: boolean) => false | ICommand`: Filter or modify your commands.
- `extraCommands?: ICommand[]`: Displayed on the right side of the toolbar.
- `autoFocus?: true`: Can be used to make `Markdown Editor` focus itself on initialization.
- `previewOptions?: ReactMarkdown.ReactMarkdownProps`: This is reset [@uiw/react-markdown-preview](https://github.com/uiwjs/react-markdown-preview/tree/e6e8462d9a5c64a7045e25adcb4928095d74ca37#options-props) settings.
- `textareaProps?: TextareaHTMLAttributes`: Set the `textarea` related props.
- ~~`renderTextarea?: (props, opts) => JSX.Element;`~~: `@deprecated` Please use ~~`renderTextarea`~~ -> `components`. Use div to replace TextArea or re-render TextArea. [#193](https://github.com/uiwjs/react-md-editor/issues/193)
- `components`: re-render textarea/toolbar element. [#419](https://github.com/uiwjs/react-md-editor/issues/419)
- `textarea` Use div to replace TextArea or re-render TextArea
- `toolbar` Override the default command element. _`toolbar`_ < _`command[].render`_
- `preview` Custom markdown preview. [#429](https://github.com/uiwjs/react-md-editor/issues/429)
- `height?: number=200`: The height of the editor. ️⚠️ `Dragbar` is invalid when **`height`** parameter percentage.
- `visibleDragbar?: boolean=true`: Show drag and drop tool. Set the height of the editor.
- `highlightEnable?: boolean=true`: Disable editing area code highlighting. The value is `false`, which increases the editing speed.
- `fullscreen?: boolean=false`: Show markdown preview.
- `overflow?: boolean=true`: Disable `fullscreen` setting body styles
- `preview?: 'live' | 'edit' | 'preview'`: Default value `live`, Show markdown preview.
- `maxHeight?: number=1200`: Maximum drag height. The `visibleDragbar=true` value is valid.
- `minHeights?: number=100`: Minimum drag height. The `visibleDragbar=true` value is valid.
- `tabSize?: number=2`: The number of characters to insert when pressing tab key. Default `2` spaces.
- `defaultTabEnable?: boolean=false`: If `false`, the `tab` key inserts a tab character into the textarea. If `true`, the `tab` key executes default behavior e.g. focus shifts to next element.
- `hideToolbar?: boolean=false`: Option to hide the tool bar.
- `enableScroll?: boolean=true`: Whether to enable scrolling.
### Development
```bash
npm run watch # Listen create type and .tsx files.
npm run css:watch # listen to the component compile and output the .css file
npm run start # Preview code example.
```
### Related
- [@uiw/react-textarea-code-editor](https://github.com/uiwjs/react-textarea-code-editor): A simple code editor with syntax highlighting.
- [@uiw/react-md-editor](https://github.com/uiwjs/react-md-editor): A simple markdown editor with preview, implemented with React.js and TypeScript.
- [@uiw/react-codemirror](https://github.com/uiwjs/react-codemirror): CodeMirror component for React. @codemirror
- [@uiw/react-monacoeditor](https://github.com/jaywcjlove/react-monacoeditor): Monaco Editor component for React.
- [@uiw/react-markdown-editor](https://github.com/uiwjs/react-markdown-editor): A markdown editor with preview, implemented with React.js and TypeScript.
- [@uiw/react-markdown-preview](https://github.com/uiwjs/react-markdown-preview): React component preview markdown text in web browser.
## Contributors
As always, thanks to our amazing contributors!
Made with [github-action-contributors](https://github.com/jaywcjlove/github-action-contributors).
### License
Licensed under the MIT License.