Uh oh!
There was an error while loading.Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork190
A simple markdown editor with preview, implemented with React.js and TypeScript.
License
uiwjs/react-md-editor
Folders and files
| Name | Name | Last commit message | Last commit date | |
|---|---|---|---|---|
Repository files navigation
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 ontextarea encapsulation, so it does not depend on any modern code editors such as Acs, CodeMirror, Monaco etc.
- 📑 Indent line or selected text by pressing tab key, with customizable indentation.
- ♻️ Based on
textareaencapsulation, does not depend on any modern code editors. - 🚧 Does not depend on the
uiwcomponent library. - 🚘 Automatic list on new lines.
- 😻 GitHub flavored markdown support.
- 🌒 Support dark-mode/night-mode@v3.11.0+.
- 💡 Supportnext.js,Use examples innext.js.
- Line/lines duplication (Ctrl+D) and movement (Alt+UpArrow/DownArrow)@v3.24.0+.
npm i @uiw/react-md-editor
or
yarn add @uiw/react-md-editor
importReactfrom"react";importMDEditorfrom'@uiw/react-md-editor';exportdefaultfunctionApp(){const[value,setValue]=React.useState("**Hello world!!!**");return(<divclassName="container"><MDEditorvalue={value}onChange={setValue}/><MDEditor.Markdownsource={value}style={{whiteSpace:'pre-wrap'}}/></div>);}
Supports for CSS Style
Use HTML comments<!--rehype:xxx--> to let Markdown support style customization.
##Title<!--rehype:style=display: flex; height: 230px; align-items: center; justify-content: center; font-size: 38px;-->Markdown Supports**Style**<!--rehype:style=color: red;-->
Ignore content display via HTML comments
Shown in GitHub readme, excluded in HTML.
#Hello World<!--rehype:ignore:start-->Hello World<!--rehype:ignore:end-->Good!
Output:
<h1>Hello World</h1><p>Good!</p>
Please note markdown needs to be sanitized if you do notcompletely trust your authors.Otherwise, your app is vulnerable to XSS. This can be achieved by addingrehype-sanitize as a plugin.
importReactfrom"react";importMDEditorfrom'@uiw/react-md-editor';importrehypeSanitizefrom"rehype-sanitize";exportdefaultfunctionApp(){const[value,setValue]=React.useState(`**Hello world!!!** <IFRAME SRC=\"#"></IFRAME>`);return(<divclassName="container"><MDEditorvalue={value}onChange={setValue}previewOptions={{rehypePlugins:[[rehypeSanitize]],}}/></div>);}
The following example can help youexclude code highlighting code from being included in the bundle.@uiw/react-md-editor/nohighlight component does not contain the code highlighting package,rehype-prism-plus,highlightEnable andshowLineNumbers functions will no longer work. (#586)highlight line
importReactfrom"react";importMDEditorfrom'@uiw/react-md-editor/nohighlight';constcode=`**Hello world!!!**\`\`\`jsfunction demo() {}\`\`\``exportdefaultfunctionApp(){const[value,setValue]=React.useState(code);return(<divclassName="container"><MDEditorvalue={value}onChange={setValue}/><MDEditor.Markdownsource={value}style={{whiteSpace:'pre-wrap'}}/></div>);}
"Below is an example that sets theplaceholder for the editor and defines the maximum input character length as10 characters."
importReactfrom"react";importMDEditorfrom'@uiw/react-md-editor';exportdefaultfunctionApp(){const[value,setValue]=React.useState("");return(<MDEditorvalue={value}onChange={setValue}textareaProps={{placeholder:'Please enter Markdown text',maxLength:10}}/>);}
importReact,{useState}from"react";importMDEditor,{commands}from'@uiw/react-md-editor';consttitle3={name:'title3',keyCommand:'title3',buttonProps:{'aria-label':'Insert title3'},icon:(<svgwidth="12"height="12"viewBox="0 0 520 520"><pathfill="currentColor"d="M15.7083333,468 C7.03242448,468 0,462.030833 0,454.666667 L0,421.333333 C0,413.969167 7.03242448,408 15.7083333,408 L361.291667,408 C369.967576,408 377,413.969167 377,421.333333 L377,454.666667 C377,462.030833 369.967576,468 361.291667,468 L15.7083333,468 Z M21.6666667,366 C9.69989583,366 0,359.831861 0,352.222222 L0,317.777778 C0,310.168139 9.69989583,304 21.6666667,304 L498.333333,304 C510.300104,304 520,310.168139 520,317.777778 L520,352.222222 C520,359.831861 510.300104,366 498.333333,366 L21.6666667,366 Z M136.835938,64 L136.835937,126 L107.25,126 L107.25,251 L40.75,251 L40.75,126 L-5.68434189e-14,126 L-5.68434189e-14,64 L136.835938,64 Z M212,64 L212,251 L161.648438,251 L161.648438,64 L212,64 Z M378,64 L378,126 L343.25,126 L343.25,251 L281.75,251 L281.75,126 L238,126 L238,64 L378,64 Z M449.047619,189.550781 L520,189.550781 L520,251 L405,251 L405,64 L449.047619,64 L449.047619,189.550781 Z"/></svg>),execute:(state,api)=>{letmodifyText=`###${state.selectedText}\n`;if(!state.selectedText){modifyText=`### `;}api.replaceSelection(modifyText);},};consttitle2={name:'title2',keyCommand:'title2',render:(command,disabled,executeCommand)=>{return(<buttonaria-label="Insert title2"disabled={disabled}onClick={(evn)=>{// evn.stopPropagation();executeCommand(command,command.groupName)}}><svgwidth="12"height="12"viewBox="0 0 520 520"><pathfill="currentColor"d="M15.7083333,468 C7.03242448,468 0,462.030833 0,454.666667 L0,421.333333 C0,413.969167 7.03242448,408 15.7083333,408 L361.291667,408 C369.967576,408 377,413.969167 377,421.333333 L377,454.666667 C377,462.030833 369.967576,468 361.291667,468 L15.7083333,468 Z M21.6666667,366 C9.69989583,366 0,359.831861 0,352.222222 L0,317.777778 C0,310.168139 9.69989583,304 21.6666667,304 L498.333333,304 C510.300104,304 520,310.168139 520,317.777778 L520,352.222222 C520,359.831861 510.300104,366 498.333333,366 L21.6666667,366 Z M136.835938,64 L136.835937,126 L107.25,126 L107.25,251 L40.75,251 L40.75,126 L-5.68434189e-14,126 L-5.68434189e-14,64 L136.835938,64 Z M212,64 L212,251 L161.648438,251 L161.648438,64 L212,64 Z M378,64 L378,126 L343.25,126 L343.25,251 L281.75,251 L281.75,126 L238,126 L238,64 L378,64 Z M449.047619,189.550781 L520,189.550781 L520,251 L405,251 L405,64 L449.047619,64 L449.047619,189.550781 Z"/></svg></button>)},execute:(state,api)=>{letmodifyText=`##${state.selectedText}\n`;if(!state.selectedText){modifyText=`## `;}api.replaceSelection(modifyText);},}functionSubChildren({ close, execute, getState, textApi, dispatch}){const[value,setValue]=useState('')constinsert=()=>{console.log('value:::',value)textApi.replaceSelection(value)}return(<divstyle={{width:120,padding:10}}><div>My Custom Toolbar</div><inputtype="text"onChange={(e)=>setValue(e.target.value)}/><buttontype="button"onClick={()=>{dispatch({$value:'~~~~~~'})console.log('> execute: >>>>>',getState())}}> State</button><buttontype="button"onClick={insert}>Insert</button><buttontype="button"onClick={()=>close()}>Close</button><buttontype="button"onClick={()=>execute()}>Execute</button></div>);}constsubChild={name:'update',groupName:'update',icon:(<svgviewBox="0 0 1024 1024"width="12"height="12"><pathfill="currentColor"d="M716.8 921.6a51.2 51.2 0 1 1 0 102.4H307.2a51.2 51.2 0 1 1 0-102.4h409.6zM475.8016 382.1568a51.2 51.2 0 0 1 72.3968 0l144.8448 144.8448a51.2 51.2 0 0 1-72.448 72.3968L563.2 541.952V768a51.2 51.2 0 0 1-45.2096 50.8416L512 819.2a51.2 51.2 0 0 1-51.2-51.2v-226.048l-57.3952 57.4464a51.2 51.2 0 0 1-67.584 4.2496l-4.864-4.2496a51.2 51.2 0 0 1 0-72.3968zM512 0c138.6496 0 253.4912 102.144 277.1456 236.288l10.752 0.3072C924.928 242.688 1024 348.0576 1024 476.5696 1024 608.9728 918.8352 716.8 788.48 716.8a51.2 51.2 0 1 1 0-102.4l8.3968-0.256C866.2016 609.6384 921.6 550.0416 921.6 476.5696c0-76.4416-59.904-137.8816-133.12-137.8816h-97.28v-51.2C691.2 184.9856 610.6624 102.4 512 102.4S332.8 184.9856 332.8 287.488v51.2H235.52c-73.216 0-133.12 61.44-133.12 137.8816C102.4 552.96 162.304 614.4 235.52 614.4l5.9904 0.3584A51.2 51.2 0 0 1 235.52 716.8C105.1648 716.8 0 608.9728 0 476.5696c0-132.1984 104.8064-239.872 234.8544-240.2816C258.5088 102.144 373.3504 0 512 0z"/></svg>),children:(props)=><SubChildren{...props}/>,execute:(state,api)=>{console.log('>>>>>>update>>>>>',state)},buttonProps:{'aria-label':'Insert title'}}exportdefaultfunctionApp(){const[value,setValue]=React.useState("Hello Markdown! `Tab` key uses default behavior");return(<divclassName="container"><MDEditorvalue={value}onChange={setValue}commands={[// Custom Toolbarstitle3,title2,commands.group([commands.title1,commands.title2,commands.title3,commands.title4,commands.title5,commands.title6],{name:'title',groupName:'title',buttonProps:{'aria-label':'Insert title'}}),commands.divider,commands.group([],subChild),]}/></div>);}
Customize the toolbar withcommands andextraCommands props.
importReactfrom"react";importMDEditor,{commands}from'@uiw/react-md-editor';exportdefaultfunctionApp(){const[value,setValue]=React.useState("Hello Markdown! `Tab` key uses default behavior");return(<divclassName="container"><MDEditorvalue={value}onChange={setValue}preview="edit"commands={[commands.codeEdit,commands.codePreview]}extraCommands={[commands.group([commands.title1,commands.title2,commands.title3,commands.title4,commands.title5,commands.title6],{name:'title',groupName:'title',buttonProps:{'aria-label':'Insert title'}}),commands.divider,commands.group([],{name:'update',groupName:'update',icon:(<svgviewBox="0 0 1024 1024"width="12"height="12"><pathfill="currentColor"d="M716.8 921.6a51.2 51.2 0 1 1 0 102.4H307.2a51.2 51.2 0 1 1 0-102.4h409.6zM475.8016 382.1568a51.2 51.2 0 0 1 72.3968 0l144.8448 144.8448a51.2 51.2 0 0 1-72.448 72.3968L563.2 541.952V768a51.2 51.2 0 0 1-45.2096 50.8416L512 819.2a51.2 51.2 0 0 1-51.2-51.2v-226.048l-57.3952 57.4464a51.2 51.2 0 0 1-67.584 4.2496l-4.864-4.2496a51.2 51.2 0 0 1 0-72.3968zM512 0c138.6496 0 253.4912 102.144 277.1456 236.288l10.752 0.3072C924.928 242.688 1024 348.0576 1024 476.5696 1024 608.9728 918.8352 716.8 788.48 716.8a51.2 51.2 0 1 1 0-102.4l8.3968-0.256C866.2016 609.6384 921.6 550.0416 921.6 476.5696c0-76.4416-59.904-137.8816-133.12-137.8816h-97.28v-51.2C691.2 184.9856 610.6624 102.4 512 102.4S332.8 184.9856 332.8 287.488v51.2H235.52c-73.216 0-133.12 61.44-133.12 137.8816C102.4 552.96 162.304 614.4 235.52 614.4l5.9904 0.3584A51.2 51.2 0 0 1 235.52 716.8C105.1648 716.8 0 608.9728 0 476.5696c0-132.1984 104.8064-239.872 234.8544-240.2816C258.5088 102.144 373.3504 0 512 0z"/></svg>),children:({ close, execute, getState, textApi})=>{return(<divstyle={{width:120,padding:10}}><div>My Custom Toolbar</div><buttontype="button"onClick={()=>console.log('> execute: >>>>>',getState())}>State</button><buttontype="button"onClick={()=>close()}>Close</button><buttontype="button"onClick={()=>execute()}>Execute</button></div>);},execute:(state,api)=>{console.log('>>>>>>update>>>>>',state)},buttonProps:{'aria-label':'Insert title'}}),commands.divider,commands.fullscreen]}/></div>);}
re-rendertoolbar element.
importReactfrom"react";importMDEditor,{commands}from'@uiw/react-md-editor';exportdefaultfunctionApp(){const[value,setValue]=React.useState("Hello Markdown! `Tab` key uses default behavior");return(<divclassName="container"><MDEditorvalue={value}onChange={setValue}preview="edit"components={{toolbar:(command,disabled,executeCommand)=>{if(command.keyCommand==='code'){return(<buttonaria-label="Insert code"disabled={disabled}onClick={(evn)=>{evn.stopPropagation();executeCommand(command,command.groupName)}}> Code</button>)}}}}/></div>);}
Custom Preview Command Tool
importReact,{useContext}from"react";importMDEditor,{commands,EditorContext}from"@uiw/react-md-editor";constButton=()=>{const{ preview, dispatch}=useContext(EditorContext);constclick=()=>{dispatch({preview:preview==="edit" ?"preview" :"edit"});};if(preview==="edit"){return(<svgwidth="12"height="12"viewBox="0 0 520 520"onClick={click}><polygonfill="currentColor"points="0 71.293 0 122 319 122 319 397 0 397 0 449.707 372 449.413 372 71.293"/><polygonfill="currentColor"points="429 71.293 520 71.293 520 122 481 123 481 396 520 396 520 449.707 429 449.413"/></svg>);}return(<svgwidth="12"height="12"viewBox="0 0 520 520"onClick={click}><polygonfill="currentColor"points="0 71.293 0 122 38.023 123 38.023 398 0 397 0 449.707 91.023 450.413 91.023 72.293"/><polygonfill="currentColor"points="148.023 72.293 520 71.293 520 122 200.023 124 200.023 397 520 396 520 449.707 148.023 450.413"/></svg>);};constcodePreview={name:"preview",keyCommand:"preview",value:"preview",icon:<Button/>};constDisable=()=>{const{ preview, dispatch}=useContext(EditorContext);return(<buttondisabled={preview==="preview"}><svgviewBox="0 0 16 16"width="12px"height="12px"><pathd="M8 0C3.6 0 0 3.6 0 8s3.6 8 8 8 8-3.6 8-8-3.6-8-8-8Zm.9 13H7v-1.8h1.9V13Zm-.1-3.6v.5H7.1v-.6c.2-2.1 2-1.9 1.9-3.2.1-.7-.3-1.1-1-1.1-.8 0-1.2.7-1.2 1.6H5c0-1.7 1.2-3 2.9-3 2.3 0 3 1.4 3 2.3.1 2.3-1.9 2-2.1 3.5Z"fill="currentColor"/></svg></button>)}constcustomButton={name:"disable",keyCommand:"disable",value:"disable",icon:<Disable/>}exportdefaultfunctionApp(){const[value,setValue]=React.useState("**Hello world!!!**");return(<divclassName="container"><div>The system automatically sets the theme</div><MDEditorvalue={value}preview="edit"extraCommands={[codePreview,customButton,commands.fullscreen]}onChange={(val)=>setValue(val)}/></div>);}
Add Help Command Tool
importReact,{useContext}from"react";importMDEditor,{commands}from"@uiw/react-md-editor";consthelp={name:"help",keyCommand:"help",buttonProps:{"aria-label":"Insert help"},icon:(<svgviewBox="0 0 16 16"width="12px"height="12px"><pathd="M8 0C3.6 0 0 3.6 0 8s3.6 8 8 8 8-3.6 8-8-3.6-8-8-8Zm.9 13H7v-1.8h1.9V13Zm-.1-3.6v.5H7.1v-.6c.2-2.1 2-1.9 1.9-3.2.1-.7-.3-1.1-1-1.1-.8 0-1.2.7-1.2 1.6H5c0-1.7 1.2-3 2.9-3 2.3 0 3 1.4 3 2.3.1 2.3-1.9 2-2.1 3.5Z"fill="currentColor"/></svg>),execute:(state,api)=>{window.open("https://www.markdownguide.org/basic-syntax/","_blank");}};exportdefaultfunctionApp(){const[value,setValue]=React.useState("**Hello world!!!**");return(<MDEditorvalue={value}preview="edit"commands={[...commands.getCommands(),help]}onChange={(val)=>setValue(val)}/>);}
Internationalization Example, You can refer tocommands-cn for internationalization.
importReact,{useContext}from"react";importMDEditor,{commands}from"@uiw/react-md-editor";import{getCommands,getExtraCommands}from"@uiw/react-md-editor/commands-cn";exportdefaultfunctionApp(){const[value,setValue]=React.useState("**Hello world!!!**");return(<MDEditorvalue={value}preview="edit"commands={[...getCommands()]}extraCommands={[...getExtraCommands()]}onChange={(val)=>setValue(val)}/>);}
body .w-md-editor-text-pre>code,body .w-md-editor-text-input {font-size:23px!important;line-height:24px!important;}
The initial height can be adjusted throughminHeight={100}. Dragbar will automatically expire. You can hide the drag button throughvisibleDragbar={false}
importReactfrom"react";importMDEditorfrom'@uiw/react-md-editor';exportdefaultfunctionApp(){const[value,setValue]=React.useState("**Hello world!!!**");return(<divclassName="container"><MDEditorvalue={value}height="100%"// minHeight={50}visibleDragbar={false}onChange={setValue}/></div>);}
importReactfrom"react";importMDEditorfrom'@uiw/react-md-editor';exportdefaultfunctionApp(){const[value,setValue]=React.useState("**Hello world!!!** <style>body{display:none;}</style> ");return(<divclassName="container"><MDEditorvalue={value}height="100%"previewOptions={{disallowedElements:['style'],}}visibleDragbar={false}onChange={setValue}/></div>);}
importReactfrom"react";importMDEditorfrom'@uiw/react-md-editor';consttextSample=`# Welcome to the Markdown Editor!This is a sample of the **React Markdown Editor**.## ✨ Features- Real-time preview- Custom styling support- Code highlighting- Auto focus at the end of the text## 📦 Sample Code\`\`\`javascriptfunction hello() { console.log("Hello, world!");}\`\`\`## 🔗 LinksVisit [uiwjs/react-md-editor](https://github.com/uiwjs/react-md-editor) for more information.`;exportdefaultfunctionApp(){const[value,setValue]=React.useState(textSample);return(<divclassName="container"><MDEditorautoFocus={true}value={value}autoFocusEnd={true}visibleDragbar={false}onChange={setValue}/></div>);}
importReactfrom"react";importMDEditorfrom'@uiw/react-md-editor';exportdefaultfunctionApp(){return(<divclassName="container"><MDEditor.Markdownsource="Hello Markdown!"/></div>);}
KaTeX is a fast, easy-to-use JavaScript library for TeX math rendering on the web, We perform math rendering throughKaTeX.
The following example is preview inCodeSandbox.
⚠️ Upgrade v2 to v3d025430
npm install katex
importReactfrom"react";importMDEditorfrom'@uiw/react-md-editor';import{getCodeString}from'rehype-rewrite';importkatexfrom'katex';import'katex/dist/katex.css';constmdKaTeX=`This is to display the\`\$\$\c = \\pm\\sqrt{a^2 + b^2}\$\$\` in one line\`\`\`KaTeXc = \\pm\\sqrt{a^2 + b^2}\`\`\``;exportdefaultfunctionApp(){const[value,setValue]=React.useState(mdKaTeX);return(<MDEditorvalue={value}onChange={(val)=>setValue(val)}previewOptions={{components:{code:({ children=[], className, ...props})=>{if(typeofchildren==='string'&&/^\$\$(.*)\$\$/.test(children)){consthtml=katex.renderToString(children.replace(/^\$\$(.*)\$\$/,'$1'),{throwOnError:false,});return<codedangerouslySetInnerHTML={{__html:html}}style={{background:'transparent'}}/>;}constcode=props.node&&props.node.children ?getCodeString(props.node.children) :children;if(typeofcode==='string'&&typeofclassName==='string'&&/^language-katex/.test(className.toLocaleLowerCase())){consthtml=katex.renderToString(code,{throwOnError:false,});return<codestyle={{fontSize:'150%'}}dangerouslySetInnerHTML={{__html:html}}/>;}return<codeclassName={String(className)}>{children}</code>;},},}}/>);}
importReact,{useState}from"react";importMDEditor,{commands,typeICommand,TextState,TextAreaTextApi}from"@uiw/react-md-editor";importdomToImagefrom"dom-to-image";consttextToImage:ICommand={name:"Text To Image",keyCommand:"text2image",buttonProps:{"aria-label":"Insert title3"},icon:(<svgwidth="12"height="12"viewBox="0 0 20 20"><pathfill="currentColor"d="M15 9c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2zm4-7H1c-.55 0-1 .45-1 1v14c0 .55.45 1 1 1h18c.55 0 1-.45 1-1V3c0-.55-.45-1-1-1zm-1 13l-6-5-2 2-4-5-4 8V4h16v11z"></path></svg>),execute:(state:TextState,api:TextAreaTextApi)=>{constdom=document.getElementsByClassName("gooooooooo")[0];if(dom){domToImage.toJpeg(dom,{}).then((dataUrl)=>{constlink=document.createElement("a");link.download="image.jpg";link.href=dataUrl;link.click();});}}};exportdefaultfunctionApp(){const[value,setValue]=useState('**Hello world!!!**');console.log('value::',value)return(<divclassName="container"><MDEditorclassName="gooooooooo"onChange={(newValue="")=>setValue(newValue)}value={value}commands={[textToImage,commands.divider]}/></div>);}
Usingmermaid to generation of diagram and flowchart from text in a similar manner as markdown
npm install mermaid
importReact,{useState,useRef,useEffect,Fragment,useCallback}from"react";importMDEditorfrom"@uiw/react-md-editor";import{getCodeString}from'rehype-rewrite';importmermaidfrom"mermaid";constmdMermaid=`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.\`\`\`mermaidgraph TDA[Hard] -->|Text| B(Round)B --> C{Decision}C -->|One| D[Result 1]C -->|Two| E[Result 2]\`\`\`\`\`\`mermaidsequenceDiagramAlice->>John: Hello John, how are you?loop Healthcheck John->>John: Fight against hypochondriaendNote right of John: Rational thoughts!John-->>Alice: Great!John->>Bob: How about you?Bob-->>John: Jolly good!\`\`\``;constrandomid=()=>parseInt(String(Math.random()*1e15),10).toString(36);constCode=({ inline, children=[], className, ...props})=>{constdemoid=useRef(`dome${randomid()}`);const[container,setContainer]=useState(null);constisMermaid=className&&/^language-mermaid/.test(className.toLocaleLowerCase());constcode=children ?getCodeString(props.node.children) :children[0]||"";useEffect(()=>{if(container&&isMermaid&&demoid.current&&code){mermaid.render(demoid.current,code).then(({ svg, bindFunctions})=>{container.innerHTML=svg;if(bindFunctions){bindFunctions(container);}}).catch((error)=>{console.log("error:",error);});}},[container,isMermaid,code,demoid]);constrefElement=useCallback((node)=>{if(node!==null){setContainer(node);}},[]);if(isMermaid){return(<Fragment><codeid={demoid.current}style={{display:"none"}}/><codeclassName={className}ref={refElement}data-name="mermaid"/></Fragment>);}return<codeclassName={className}>{children}</code>;};exportdefaultfunctionApp(){const[value,setValue]=useState(mdMermaid);return(<MDEditoronChange={(newValue="")=>setValue(newValue)}textareaProps={{placeholder:"Please enter Markdown text"}}height={500}value={value}previewOptions={{components:{code:Code}}}/>);}
npm install next-remove-importsnpm install @uiw/react-md-editor@v3.6.0
// next.config.jsconstremoveImports=require('next-remove-imports')();module.exports=removeImports({});
import"@uiw/react-md-editor/markdown-editor.css";import"@uiw/react-markdown-preview/markdown.css";importdynamicfrom"next/dynamic";import{useState}from"react";import*ascommandsfrom"@uiw/react-md-editor/commands"constMDEditor=dynamic(()=>import("@uiw/react-md-editor"),{ssr:false});functionHomePage(){const[value,setValue]=useState("**Hello world!!!**");return(<div><MDEditorvalue={value}onChange={setValue}/></div>);}exportdefaultHomePage;
By default, thedark-mode is automatically switched according to the system. If you need to switch manually, just set thedata-color-mode="dark" parameter for body.
<htmldata-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. Setting theme styles withdata-color-mode="light".
<divdata-color-mode="light"><divclassName="wmde-markdown-var"></div><MDEditorsource="Hello World!"/></div>
value: string: The Markdown value.onChange?: (value?: string, event?: React.ChangeEvent<HTMLTextAreaElement>, state?: ContextStore): Event handler for theonChangeevent.onHeightChange?: ((value?: CSSProperties['height'], oldValue?: CSSProperties['height'], state?: ContextStore): editor height change listener.onStatistics?: (data: Statistics) => void;Some data on the statistics editor.commands?: ICommand[]: An array ofICommand, which, each one, contain acommandsproperty. 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 makeMarkdown Editorfocus itself on initialization.autoFocusEnd?: false: Can be used to makeMarkdown Editorfocus on the end of text on initialization.previewOptions?: ReactMarkdown.ReactMarkdownProps: This is reset@uiw/react-markdown-preview settings.textareaProps?: TextareaHTMLAttributes: Set thetextarearelated props.:renderTextarea?: (props, opts) => JSX.Element;@deprecatedPlease use->renderTextareacomponents. Use div to replace TextArea or re-render TextArea.#193components: re-render textarea/toolbar element.#419textareaUse div to replace TextArea or re-render TextAreatoolbarOverride the default command element.toolbar<command[].renderpreviewCustom markdown preview.#429
height?: number=200: The height of the editor. ️⚠️ Dragbaris invalid whenheightparameter 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 isfalse, which increases the editing speed.fullscreen?: boolean=false: Show markdown preview.overflow?: boolean=true: Disablefullscreensetting body stylespreview?: 'live' | 'edit' | 'preview': Default valuelive, Show markdown preview.maxHeight?: number=1200: Maximum drag height. ThevisibleDragbar=truevalue is valid.minHeight?: number=100: Minimum drag height. ThevisibleDragbar=truevalue is valid.tabSize?: number=2: The number of characters to insert when pressing tab key. Default2spaces.defaultTabEnable?: boolean=false: Iffalse, thetabkey inserts a tab character into the textarea. Iftrue, thetabkey 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.
- Install dependencies
$ npm install# Installation dependencies$ npm run build# Compile all package
- Development
@uiw/react-md-editorpackage:
$cd core# listen to the component compile and output the .js file# listen for compilation output type .d.ts file$ npm run watch# Monitor the compiled package `@uiw/react-md-editor`
- Launch documentation site
npm run start
- @uiw/react-textarea-code-editor: A simple code editor with syntax highlighting.
- @uiw/react-md-editor: A simple markdown editor with preview, implemented with React.js and TypeScript.
- @uiw/react-codemirror: CodeMirror component for React. @codemirror
- @uiw/react-monacoeditor: Monaco Editor component for React.
- @uiw/react-markdown-editor: A markdown editor with preview, implemented with React.js and TypeScript.
- @uiw/react-markdown-preview: React component preview markdown text in web browser.
As always, thanks to our amazing contributors!
Made withcontributors.
Licensed under the MIT License.
About
A simple markdown editor with preview, implemented with React.js and TypeScript.
Topics
Resources
License
Uh oh!
There was an error while loading.Please reload this page.
Stars
Watchers
Forks
Sponsor this project
Uh oh!
There was an error while loading.Please reload this page.



























