Plugins can insert buttons into menu bar, and control editor's content.
Through the use and unuse APIs, or through the plugins property.
See the API documentation and configure documentation
Those plugins are built-in plugin:
- header: title
- font-bold: bold
- font-italic: italic
- font-underline: underline
- font-strikethrough: strikethrough
- list-unordered: unordered
- list-ordered: ordered
- block-quote: quote
- block-wrap: wrap new line
- block-code-inline: inline code
- block-code-block: block code
- table: table
- image: image upload
- link: hyperlinks
- clear: clear texts
- logger: history (undo/redo)
- mode-toggle: toggle view mode
- full-screen: toggle full screen
- auto-resize: auto-resize plugin (disabled by default)
- tab-insert: insert tab or spaces (disabled by default)
[
'header',
'font-bold',
'font-italic',
'font-underline',
'font-strikethrough',
'list-unordered',
'list-ordered',
'block-quote',
'block-wrap',
'block-code-inline',
'block-code-block',
'table',
'image',
'link',
'clear',
'logger',
'mode-toggle',
'full-screen',
'tab-insert'
]- If you enabled
loggerplugin, it will auto registerundoandredoAPI, you can use them withcallPluginApi.
import Editor, { Plugins } from 'react-markdown-editor-lite';
Editor.unuse(Plugins.Header); // header
Editor.unuse(Plugins.FontBold); // font-boldimport Editor, { Plugins } from 'react-markdown-editor-lite';
Editor.use(Plugins.AutoResize, {
min: 200, // min height
max: 600, // max height
});By default, Markdown Editor will lose input focus when user type a Tab key. You can use the built-in tab-insert plugin to solve this problem.
import Editor, { Plugins } from 'react-markdown-editor-lite';
Editor.use(Plugins.TabInsert, {
/**
* Number of spaces will be inputted when user type a Tab key.
* Especially, note that 1 means a '\t' instead of ' '.
* Default value is 1.
*/
tabMapValue: 1,
});divider is a special plugin, you can not un-use it, and you also shouldn't use it. If you want to insert a divider into toolbar, just put divider into the plugins array.
import Editor, { Plugins } from 'react-markdown-editor-lite';
const plugins = ['header', 'table', 'divider', 'link', 'clear', 'divider', 'font-bold'];
<Editor plugins={plugins} />import Editor, { Plugins } from 'react-markdown-editor-lite';
import MyPlugin from './MyPlugin';
Editor.use(MyPlugin);
// Remove built-in header plugin here, in all editors
Editor.unuse(Plugins.Header);
// Remove built-in image plugin here, only this editor
const plugins = ['header', 'table', 'my-plugins', 'link', 'clear', 'logger', 'mode-toggle', 'full-screen'];
<Editor plugins={plugins} />Plugin is a React Component, and must extend PluginComponent or implement FunctionPlugin.
In PluginComponent, you can:
- Get editor instance by
this.editor, and call all editor's APIs. - Get editor's config by
this.editorConfig. - Get the options passed in use by
this.getConfigorthis.props.config.
In PluginComponent, you can:
- Get editor instance by
props.editor, and call all editor's APIs. - Get editor's config by
props.editorConfig. - Get the options passed in use by
props.config.
In following, we written a counter, insert an increasing number into the editor with each click. The starting number is read from the options passed in use.
import { PluginComponent } from 'react-markdown-editor-lite';
interface CounterState {
num: number;
}
interface CounterConfig {
start: number;
}
class Counter extends PluginComponent<CounterState, CounterConfig> {
// Define plugin name here, must be unique
static pluginName = 'counter';
// Define which place to be render, default is left, you can also use 'right'
static align = 'left';
// Define default config if required
static defaultConfig = {
start: 0
}
constructor(props: any) {
super(props);
this.handleClick = this.handleClick.bind(this);
this.state = {
num: this.getConfig('start')
};
}
handleClick() {
// Call API, insert number to editor
this.editor.insertText(this.state.num);
// Update itself's state
this.setState({
num: this.state.num++
});
}
render() {
return (
<span
className="button button-type-counter"
title="Counter"
onClick={this.handleClick}
>
{this.state.num}
</span>
);
}
}
// Usage:
Editor.use(Counter, {
start: 10
});
// Or:
<Editor plugins={[Counter, { start: 20 }]} />You can also use function component to write a plugin
import React from 'react';
import { FunctionPlugin } from 'react-markdown-editor-lite';
interface CounterState {
num: number;
}
interface CounterConfig {
start: number;
}
const Counter: FunctionPlugin<CounterConfig> = (props) => {
const [num, setNum] = React.useState(props.config.start);
const handleClick = () => {
// Call API, insert number to editor
props.editor.insertText(num);
// Update itself's state
setNum(num + 1);
}
return (
<span
className="button button-type-counter"
title="Counter"
onClick={handleClick}
>
{num}
</span>
);
}
// Must define plugin name
Counter.pluginName = 'counter';
// Define default config if required
Counter.defaultConfig = {
start: 0
}
Counter.align = 'left';
// Usage:
Editor.use(Counter, {
start: 10
});
// Or:
<Editor plugins={[Counter, { start: 20 }]} />Yes, just return a empty element (such as <span></span>, etc) in render method.