React version markdown editor MD editor RT, supporting SSR

Time:2022-1-8

md-editor-rtIt is a vue3 version editor developed when learning vue3 some time agomd-editor-v3For the same series of projects, it is the react version, because the vue3 version is also usedtsxComplete, so the code of react version is not different.

Author’sBlogFront end content is usingnextjsDeveloped, and content management is usedvueDeveloped, the functions of extracting and editing articles and content rendering form this project.

1. Preview

1.1 function Preview

  1. Quick insert content toolbar, editor browser full screen, full screen in page, etc;
  2. Built in white theme and dark theme, support binding switching;
  3. Support shortcut key to insert content;
  4. It supports the use of prettier to format content (introduced by CDN, only supports the formatting of MD content, and can be set and closed in the code);
  5. Support multiple languages and self expanding languages;
  6. Support copying, pasting and uploading pictures, cutting and uploading pictures;
  7. Support rendering mode (no editor is displayed, only MD preview content is displayed without additional monitoring);
  8. supportssr, support innextjsUsed in;

1.2 online preview

Document and online preview:Portal

1.3 picture preview

Default mode

React version markdown editor MD editor RT, supporting SSR

Diablo mode

React version markdown editor MD editor RT, supporting SSR

2. Basic use

The react version is not currently exportedumdedition.

2.1 general single page application

import React, { useState } from 'react';
import Editor from 'md-editor-rt';
import './index.less';

export default () => {
  const [md, setMd] = useState('');
  return <Editor theme="dark" modelValue={md} onChange={(v) => setMd(v)} />;
};

2.2 server rendering

Server side rendering is generally providedmarkdownInstead of loading the entire editor, the following example is usedPreview mode onlyThe situation.

import React, { useState } from 'react';
import Editor from 'md-editor-rt';
import './index.less';

export default () => {
  const [md] = useState('# title');
  
  //Preview only mode only provides MD text without changing the text
  return <Editor editorId="article-content" theme="dark" modelValue={md} previewOnly />;
};

In terms of writing, there is no difference. It is worth noting that it is best to provide it when rendering on the servereditorIdAttribute, because the editor generates randomly by defaulteditorIdTherefore, it will cause the server sidehtmlContent and client renderedhtmlThe content is inconsistent and an error is prompted (this problem can be reproduced in the nextjs basic environment).

2.3 Title Navigation implementation

The react version was originally availableonGetCatalogProperty in the editor every timerenderThis method will be called after, and the title in the markdown content will be passed back as a list. The structure is as follows:

interface HeadList {
  text: string;
  level: 1 | 2 | 3 | 4 | 5 | 6;
}

// eg
Const [heads, setheads] = usestate < headlist > ([{text: 'Preview', level: '2'}]);

Open source on the author’s blogblog-template-nextjsIn, the navigation menu has been encapsulated based on antd, which is quite simple to use:

import Topicfy from '@/Topicfy';

//Directly assign the title list obtained from 'ongetcatalog' to the 'topicaly' component
<Topicfy heads={heads} />

3. Function demonstration of editor

3.1 extension library link

Editor extensions are mostly usedcdn, considering that there is no external network, the intranet link extension is supported. Demonstration (assuming that all external libraries are in the root directory):

import React, { useState } from 'react';
import MdEditor from 'md-editor-rt';
import 'md-editor-rt/lib/style.css';

export default () => {
  const [text] = useState('');

  return (
    <MdEditor
      modelValue={text}
      highlightJs="/highlight.min.js"
      highlightCss="/atom-one-dark.min.css"
      prettierCDN="/standalone.js"
      prettierMDCDN="/parser-markdown.js"
      cropperJs="/cropper.min.js"
      cropperCss="/cropper.min.css"
      iconfontJs="/iconfont.js"
    />
  );
};

3.2 toolbar customization

All toolbars are by default, and shortcut keys are bound to each function. If you need to display toolbars selectively, two APIs are provided:toolbarsandtoolbarsExclude, the former displays all in the array, the latter masks all in the array, and the latter has a greater weight. Here is a reference:

Case not displayedgithubButton

import React, { useState } from 'react';
import MdEditor from 'md-editor-rt';
import 'md-editor-rt/lib/style.css';

export default () => {
  const [data] = useState({
    text: '',
    toobars: [
      'bold',
      'underline',
      'italic',
      'strikeThrough',
      'sub',
      'sup',
      'quote',
      'unorderedList',
      'orderedList',
      'codeRow',
      'code',
      'link',
      'image',
      'table',
      'revoke',
      'next',
      'save',
      'pageFullscreen',
      'fullscreen',
      'preview',
      'htmlPreview'
    ],
    toolbarsExclude: ['github']
  });

  return (
    <>
      <MdEditor modelValue={data.text} toolbars={data.toobars} />
      <MdEditor modelValue={data.text} toolbarsExclude={data.toolbarsExclude} />
    </>
  );
};

3.3 extended language

The editor has built-in Chinese and English by default, and both can be overridden through the extended API. This function is mainly used to set content prompts, such as the title in the pop-up window.

To expand a language, we call itzh-NB

import React, { useState } from 'react';
import MdEditor, { StaticTextDefaultValue } from 'md-editor-rt';
import 'md-editor-rt/lib/style.css';

const languageUserDefined: { 'zh-NB': StaticTextDefaultValue } = {
  'zh-NB': {
    toolbarTips: {
      Bold: 'bold',
      Underline: 'underline',
      Italic: 'Italic',
      Strikethrough: 'strikethrough',
      Title: 'title',
      Sub: 'subscript',
      Sup: 'superscript',
      Quote: 'reference',
      Unorderedlist: 'unordered list',
      Orderedlist: 'ordered list',
      Coderow: 'in line code',
      Code: 'block level code',
      Link: 'link',
      Image: 'picture',
      Table: 'table',
      Revoke: 'back',
      Next: 'forward',
      Save: 'Save',
      Prettier: 'beautify',
      Pagefullscreen: 'browser full screen',
      Fullscreen: 'full screen',
      Preview: 'Preview',
      Htmlpreview: 'HTML code Preview',
      GitHub: 'source address'
    },
    titleItem: {
      H1: 'first level title',
      H2: 'secondary title',
      H3: 'Level 3 title',
      H4: 'level 4 title',
      H5: 'level 5 title',
      H6: 'level 6 title'
    },
    linkModalTips: {
      Title: 'Add',
      Desclabel: 'link Description:',
      Desclableplaceholder: 'please enter a description...',
      Urllabel: 'link address:',
      Urllableplaceholder: 'please enter a link...',
      Buttonok: 'OK',
      Buttonupload: 'upload'
    },
    clipModalTips: {
      Title: 'clip image upload',
      Buttonupload: 'upload'
    },
    copyCode: {
      Text: 'copy code',
      Tips: 'copied'
    }
  }
};

export default () => {
  const [data] = useState({
    text: '',
    language: 'zh-NB',
    languageUserDefined
  });

  return (
    <MdEditor
      modelValue={data.text}
      language={data.language}
      languageUserDefined={data.languageUserDefined}
    />
  );
};

If key = ‘zh CN’, Chinese coverage can be realized, and so on.

3.4 topic switching

This one is relatively simple and built-inDark themeandDefault theme, passthemeAPI switching. The demo is as follows:

import React, { useState } from 'react';
import MdEditor from 'md-editor-rt';
import 'md-editor-rt/lib/style.css';

export default () => {
  const [data] = useState({
    text: '',
    theme: 'dark'
  });
  return <MdEditor modelValue={data.text} theme={data.theme} />;
};

ending

For more updates, please pay attention to:md-editor-rt

Recommended Today

Proper memory alignment in go language

problem type Part1 struct { a bool b int32 c int8 d int64 e byte } Before we start, I want you to calculatePart1What is the total occupancy size? func main() { fmt.Printf(“bool size: %d\n”, unsafe.Sizeof(bool(true))) fmt.Printf(“int32 size: %d\n”, unsafe.Sizeof(int32(0))) fmt.Printf(“int8 size: %d\n”, unsafe.Sizeof(int8(0))) fmt.Printf(“int64 size: %d\n”, unsafe.Sizeof(int64(0))) fmt.Printf(“byte size: %d\n”, unsafe.Sizeof(byte(0))) fmt.Printf(“string size: %d\n”, […]