@uiw/react-markdown-editor
Version:
A markdown editor with preview, implemented with React.js and TypeScript.
317 lines (260 loc) β’ 10.4 kB
Markdown
<p align="center">
<a href="https://github.com/uiwjs/react-markdown-editor">
<img alt="React Markdown Editor logo" src="./website/logo.svg?sanitize=true">
</a>
</p>
<!--dividing-->
<p align="center">
<a href="https://github.com/uiwjs/react-markdown-editor/actions">
<img alt="Build & Deploy" src="https://github.com/uiwjs/react-markdown-editor/actions/workflows/ci.yml/badge.svg">
</a>
<a href="https://www.npmjs.com/package/@uiw/react-markdown-editor">
<img alt="NPM Download" src="https://img.shields.io/npm/dm/@uiw/react-markdown-editor.svg?style=flat">
</a>
<a href="https://www.npmjs.com/package/@uiw/react-markdown-editor">
<img alt="npm version" src="https://img.shields.io/npm/v/@uiw/react-markdown-editor.svg">
</a>
</p>
<p align="center">
A markdown editor with preview, implemented with React.js and TypeScript.
</p>
<!--rehype:ignore:start-->
[](https://uiwjs.github.io/react-markdown-editor/)
<!--rehype:ignore:end-->
> Migrate from @uiw/react-markdown-editor [4.x to 5.x.](https://github.com/uiwjs/react-markdown-editor/releases/tag/v5.0.0)
```bash
npm i @uiw/react-markdown-editor
```
<!--rehype:ignore:start-->
Official document [demo preview](https://uiwjs.github.io/react-markdown-editor/) ([π¨π³δΈε½ιεη½η«](http://uiw.gitee.io/react-markdown-editor/))
<!--rehype:ignore:end-->
```jsx
import MarkdownEditor from '@uiw/react-markdown-editor';
import React from 'react';
import ReactDOM from 'react-dom';
const Dome = () => (
<MarkdownEditor
value={this.state.markdown}
onChange={this.updateMarkdown}
/>
);
ReactDOM.render(<Dome />, document.getElementById('app'));
```
[](https://codesandbox.io/embed/react-markdown-editor-ybpce?file=/src/App.js)
```jsx
import MarkdownEditor from '@uiw/react-markdown-editor';
import { createRoot } from 'react-dom/client';
import React, { useState } from 'react';
function App() {
const [markdown, setMarkdown] = useState("");
return (
<MarkdownEditor
value="# This is a H1 \n## This is a H2 \n###### This is a H6"
onChange={(value, viewUpdate) => setMarkdown(value)}
/>
);
}
export default App;
```
[](https://codesandbox.io/embed/react-markdown-editorcustom-toolbars-forked-r9ocu?fontsize=14&hidenavigation=1&theme=dark)
```jsx
import React from "react";
import ReactDOM from "react-dom";
import MarkdownEditor from '@uiw/react-markdown-editor';
const title2 = {
name: 'title2',
keyCommand: 'title2',
button: { 'aria-label': 'Add title text' },
icon: (
<svg width="12" height="12" viewBox="0 0 512 512">
<path fill="currentColor" d="M496 80V48c0-8.837-7.163-16-16-16H320c-8.837 0-16 7.163-16 16v32c0 8.837 7.163 16 16 16h37.621v128H154.379V96H192c8.837 0 16-7.163 16-16V48c0-8.837-7.163-16-16-16H32c-8.837 0-16 7.163-16 16v32c0 8.837 7.163 16 16 16h37.275v320H32c-8.837 0-16 7.163-16 16v32c0 8.837 7.163 16 16 16h160c8.837 0 16-7.163 16-16v-32c0-8.837-7.163-16-16-16h-37.621V288H357.62v128H320c-8.837 0-16 7.163-16 16v32c0 8.837 7.163 16 16 16h160c8.837 0 16-7.163 16-16v-32c0-8.837-7.163-16-16-16h-37.275V96H480c8.837 0 16-7.163 16-16z" />
</svg>
),
execute: ({ state, view }) => {
if (!state || !view) return;
const lineInfo = view.state.doc.lineAt(view.state.selection.main.from);
let mark = '#';
const matchMark = lineInfo.text.match(/^
if (matchMark && matchMark[0]) {
const txt = matchMark[0];
if (txt.length < 6) {
mark = txt + '#';
}
}
if (mark.length > 6) {
mark = '#';
}
const title = lineInfo.text.replace(/^
view.dispatch({
changes: {
from: lineInfo.from,
to: lineInfo.to,
insert: `${mark}${title}`
},
// selection: EditorSelection.range(lineInfo.from + mark.length, lineInfo.to),
selection: { anchor: lineInfo.from + mark.length },
});
},
};
const Dome = () => (
<MarkdownEditor
value="Hello Markdown!"
toolbars={[
'bold', 'italic', 'header', title2
]}
/>
);
export default Dome;
```
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-markdown-editor-72s9d?fontsize=14&hidenavigation=1&theme=dark)
```bash
npm install next-remove-imports
npm install @uiw/react-markdown-editor
```
```js
// next.config.js
const removeImports = require('next-remove-imports')();
module.exports = removeImports({});
```
```jsx
import dynamic from 'next/dynamic';
import '@uiw/react-markdown-editor/markdown-editor.css';
import '@uiw/react-markdown-preview/markdown.css';
const MarkdownEditor = dynamic(
() => import("@uiw/react-markdown-editor").then((mod) => mod.default),
{ ssr: false }
);
function HomePage() {
return (
<div>
<MarkdownEditor value="Hello Markdown!" />
</div>
);
}
export default HomePage;
```
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 html Element.
```html
<html data-color-mode="dark">
```
```js
document.documentElement.setAttribute('data-color-mode', 'dark')
document.documentElement.setAttribute('data-color-mode', 'light')
```
Inherit custom color variables by adding `.wmde-markdown-var` selector.
```jsx
const Demo = () => {
return (
<div>
<div className="wmde-markdown-var"> </div>
<MarkdownEditor value="Hello Markdown!" />
</div>
)
}
```
- `value (string)` - the raw markdown that will be converted to html (**required**)
- `visible?: boolean` - Shows a preview that will be converted to html.
- `toolbars?: ICommand[] | string[]` - Tool display settings.
- `toolbarsMode?: ICommand[] | string[]` - Tool display settings.
- `onChange?:function(editor: IInstance, data: CodeMirror.EditorChange, value: string)` - called when a change is made
- `onBlur?: function(editor: IInstance, event: Event)` - event occurs when an object loses focus
- `previewProps` - [react-markdown options](https://github.com/uiwjs/react-markdown-preview/tree/v2.1.0#options-props)
```ts
import { ReactCodeMirrorProps } from '@uiw/react-codemirror';
export interface IMarkdownEditor extends ReactCodeMirrorProps {
className?: string;
prefixCls?: string;
/** The raw markdown that will be converted to html (**required**) */
value?: string;
/** Shows a preview that will be converted to html. */
visible?: boolean;
visibleEditor?: boolean;
/** Option to hide the tool bar. */
hideToolbar?: boolean;
/** Tool display settings. */
toolbars?: IToolBarProps['toolbars'];
/** Tool display settings. */
toolbarsMode?: IToolBarProps['toolbars'];
/** Override the default preview component */
renderPreview?: (props: MarkdownPreviewProps, visible: boolean) => React.ReactNode;
/** [@uiw/react-markdown-preview](https://github.com/uiwjs/react-markdown-preview#options-props) options */
previewProps?: MarkdownPreviewProps;
}
```
```ts
import React from 'react';
import { ReactCodeMirrorRef } from '@uiw/react-codemirror';
import { MarkdownPreviewProps, MarkdownPreviewRef } from '@uiw/react-markdown-preview';
export interface ToolBarProps {
editor?: ReactCodeMirrorRef;
preview: React.RefObject<MarkdownPreviewRef>;
container: React.RefObject<HTMLDivElement>;
containerEditor: React.RefObject<HTMLDivElement>;
editorProps: IMarkdownEditor;
}
export interface MarkdownEditorRef {
editor: React.RefObject<ReactCodeMirrorRef> | null;
preview?: React.RefObject<MarkdownPreviewRef> | null;
}
export interface IToolBarProps<T = keyof typeof defaultCommands | ICommand> extends ToolBarProps {
className?: string;
editorProps: IMarkdownEditor;
mode?: boolean;
prefixCls?: string;
toolbars?: T[];
onClick?: (type: string) => void;
}
export declare type ButtonHandle = (command: ICommand, props: IMarkdownEditor, options: ToolBarProps) => JSX.Element;
export declare type ICommand = {
icon?: React.ReactElement;
name?: string;
keyCommand?: string;
button?: ButtonHandle | React.ButtonHTMLAttributes<HTMLButtonElement>;
execute?: (editor: ReactCodeMirrorRef) => void;
};
export declare const defaultCommands: {
bold: ICommand;
italic: ICommand;
header: ICommand;
strike: ICommand;
underline: ICommand;
olist: ICommand;
ulist: ICommand;
link: ICommand;
todo: ICommand;
image: ICommand;
fullscreen: ICommand;
preview: ICommand;
};
export declare const getCommands: () => ICommand[];
export declare const getModeCommands: () => ICommand[];
```
```bash
npm run watch
npm run start
npm run doc
```
- [@uiw/react-textarea-code-editor](https://github.com/uiwjs/react-textarea-code-editor): A simple code editor with syntax highlighting.
- [@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-md-editor](https://github.com/uiwjs/react-md-editor): A simple 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.
As always, thanks to our amazing contributors!
<a href="https://github.com/uiwjs/react-markdown-editor/graphs/contributors">
<img src="https://uiwjs.github.io/react-markdown-editor/CONTRIBUTORS.svg" />
</a>
Made with [action-contributors](https://github.com/jaywcjlove/github-action-contributors).
Licensed under the MIT License.