react-markdown-editor

uiwjsMIT更新放缓

基于 React 和 TypeScript 的 Markdown 编辑器组件,带实时预览和代码高亮,可直接嵌入前端项目使用。

A markdown editor with preview, implemented with React.js and TypeScript.

v6.1.4发布于 2025-05-01 17:50 UTC382star37fork同步于 2026-11-07 07:33 UTC

怎么上手

从 README 代码块原样提取,可能是其中一种安装方式
npm i @uiw/react-markdown-editor
硬件要求

README 没有说明硬件要求。

下载:源码 zip·GitHub Releases(安装包)本站不镜像安装包

项目说明

这个项目的说明还在生成中,先参考下面「最近发版」和 README。

最近发版

5 个版本v6.1.4
  1. v6.1.4最新正式版2025-05-01 · 2025-05-01 17:50 UTC
  2. v6.1.22024-06-23 · 2024-06-23 16:07 UTC
    查看更新说明
  3. v6.1.12024-04-21 · 2024-04-21 10:27 UTC
    查看更新说明
  4. v6.1.02024-03-14 · 2024-03-14 11:55 UTC
    查看更新说明

    npm bundle size npm version

    Documentation v6.1.0: https://raw.githack.com/uiwjs/react-markdown-editor/6a8237e/index.html
    Comparing Changes: https://github.com/uiwjs/react-markdown-editor/compare/v6.0.1...v6.1.0

    npm i @uiw/[email protected]
    
    • 🌟 feat: export more commands. #217 d5c6858 @jaywcjlove
  5. v6.0.12024-03-14 · 2024-03-14 11:44 UTC
    查看更新说明

    npm bundle size npm version

    Documentation v6.0.1: https://raw.githack.com/uiwjs/react-markdown-editor/00ca654/index.html
    Comparing Changes: https://github.com/uiwjs/react-markdown-editor/compare/v6.0.0...v6.0.1

    npm i @uiw/[email protected]
    
    • 🌟 feat: Add className identifier to fullscreen mode. #217 155e77a @jaywcjlove
    • 🌟 feat: Enhance the fullscreen command. #217 3d05153 @jaywcjlove
    • 💄 chore(deps): update dependency husky to v9 (#216) 3f893c3 @renovate-bot
    • 💄 chore: modify husky config. (#216) 64985d0 @jaywcjlove

用户点评

登录用户的真实使用记录,可按版本和硬件筛选
共 0 条

    还没有人点评。第一个说出真实体验的人最有价值。

    README 原文

    未翻译

    React Markdown Editor

    Migrate from @uiw/react-markdown-editor 4.x to 5.x.

    Install

    npm i @uiw/react-markdown-editor
    

    Document

    Official document demo preview (🇨🇳中国镜像网站)

    Basic Usage

    import React from 'react';
    import MarkdownEditor from '@uiw/react-markdown-editor';
    
    const mdStr = `# This is a H1  \n## This is a H2  \n###### This is a H6`;
    
    const Dome = () => {
      return (
        <MarkdownEditor
          value={mdStr}
          onChange={(value, viewUpdate) => {
    
          }}
        />
      )
    };
    
    export default Dome;
    

    Controlled Usage

    Open in CodeSandbox

    import React, { useState } from 'react';
    import MarkdownEditor from '@uiw/react-markdown-editor';
    
    const mdStr = `# This is a H1  \n## This is a H2  \n###### This is a H6`;
    export default function App() {
      const [markdown, setMarkdown] = useState(mdStr);
      return (
        <MarkdownEditor
          value={markdown}
          height="200px"
          onChange={(value, viewUpdate) => setMarkdown(value)}
        />
      );
    }
    

    Only Markdown Preview

    Open in CodeSandbox

    This markdown preview sub-component is a direct export @uiw/react-markdown-preview component, API documentation, please check @uiw/react-markdown-preview.

    import React from 'react';
    import MarkdownEditor from '@uiw/react-markdown-editor';
    
    const mdStr = `# This is a H1  \n## This is a H2  \n###### This is a H6`;
    function App() {
      return (
        <MarkdownEditor.Markdown source={mdStr} height="200px" />
      );
    }
    
    export default App;
    

    Custom Toolbars

    Open in CodeSandbox

    import React from "react";
    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!"
        height="200px"
        toolbars={[
          'bold', title2
        ]}
      />
    );
    
    export default Dome;
    

    Disable preview feature

    Open in CodeSandbox

    import React from "react";
    import MarkdownEditor from '@uiw/react-markdown-editor';
    
    const Dome = () => (
      <MarkdownEditor
        value="Hello Markdown!"
        height="200px"
        enablePreview={false}
      />
    );
    
    export default Dome;
    

    Support Nextjs

    Use examples in nextjs.

    Open in CodeSandbox #52 #224

    npm install next-remove-imports
    npm install @uiw/react-markdown-editor
    
    // next.config.js
    const removeImports = require('next-remove-imports')();
    module.exports = removeImports({});
    
    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;
    

    Support dark-mode/night-mode

    By default, the 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 data-color-mode="dark">
    
    document.documentElement.setAttribute('data-color-mode', 'dark')
    document.documentElement.setAttribute('data-color-mode', 'light')
    

    Inherit custom color variables by adding .wmde-markdown-var selector.

    const Demo = () => {
      return (
        <div>
          <div className="wmde-markdown-var"> </div>
          <MarkdownEditor value="Hello Markdown!" />
        </div>
      )
    }
    

    Props

    • 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
    • onPreviewMode?: (isHide: boolean) => void - Edit mode and preview mode switching event
    • previewProps - react-markdown options
    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;
      /** Override the default preview component */
      renderPreview?: (props: MarkdownPreviewProps, initVisible: boolean) => React.ReactNode;
      /** Preview expanded width @default `50%` */
      previewWidth?: string;
      /** Whether to enable preview function @default `true` */
      enablePreview?: boolean;
      /** Whether to enable scrolling */
      enableScroll?: boolean;
      /** Tool display settings. */
      toolbars?: Commands[];
      /** The tool on the right shows the settings. */
      toolbarsMode?: Commands[];
      /** Tool display filter settings. */
      toolbarsFilter?: (tool: Commands, idx: number) => boolean;
      /** Toolbar on bottom */
      toolbarBottom?: boolean;
      /** Option to hide the tool bar. @deprecated The next major version will be deprecated. Please use `showToolbar`. */
      hideToolbar?: boolean;
      /** Option to hide the tool bar. */
      showToolbar?: boolean;
      /** [@uiw/react-markdown-preview](https://github.com/uiwjs/react-markdown-preview#options-props) options */
      previewProps?: MarkdownPreviewProps;
      /** replace the default `extensions` */
      reExtensions?: ReactCodeMirrorProps['extensions'];
      /** Edit mode and preview mode switching event */
      onPreviewMode?: (isHide: boolean) => void;
    }
    
    import React from 'react';
    import { ReactCodeMirrorRef } from '@uiw/react-codemirror';
    import { MarkdownPreviewProps, MarkdownPreviewRef } from '@uiw/react-markdown-preview';
    export * from '@uiw/react-markdown-preview';
    export interface ToolBarProps {
      editor: React.RefObject<ReactCodeMirrorRef>;
      preview: React.RefObject<HTMLDivElement>;
      container: React.RefObject<HTMLDivElement>;
      containerEditor: React.RefObject<HTMLDivElement>;
      editorProps: IMarkdownEditor;
    }
    export interface MarkdownEditorRef {
      editor: React.RefObject<ReactCodeMirrorRef> | null;
      preview?: React.RefObject<MarkdownPreviewRef> | null;
    }
    export declare type Commands = keyof typeof defaultCommands | ICommand;
    export interface IToolBarProps<T = Commands> extends ToolBarProps {
      className?: string;
      editorProps: IMarkdownEditor;
      mode?: boolean;
      prefixCls?: string;
      toolbars?: T[];
      onClick?: (type: string) => void;
    }
    declare const MarkdownEditor: MarkdownEditorComponent;
    declare type MarkdownEditorComponent = React.FC<React.PropsWithRef<IMarkdownEditor>> & {
      Markdown: typeof MarkdownPreview;
    };
    export default MarkdownEditor;
    
    import { ReactCodeMirrorRef } from '@uiw/react-codemirror';
    import { MarkdownPreviewProps, MarkdownPreviewRef } from '@uiw/react-markdown-preview';
    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: {
      undo: ICommand;
      redo: ICommand;
      bold: ICommand;
      italic: ICommand;
      header: ICommand;
      strike: ICommand;
      underline: ICommand;
      quote: ICommand;
      olist: ICommand;
      ulist: ICommand;
      todo: ICommand;
      link: ICommand;
      image: ICommand;
      code: ICommand;
      codeBlock: ICommand;
      fullscreen: ICommand;
      preview: ICommand;
    };
    export declare const getCommands: () => ICommand[];
    export declare const getModeCommands: () => ICommand[];
    export declare const defaultTheme: import("@codemirror/state").Extension;
    

    Development

    npm run watch # Listen create type and .tsx files.
    npm run start # Preview code example.
    
    npm run doc
    

    Related

    Contributors

    As always, thanks to our amazing contributors!

    Made with action-contributors.

    License

    Licensed under the MIT License.