
React.js 및 TypeScript와 함께 구현 된 미리보기가있는 간단한 마크 다운 편집기. 이 React 구성 요소는 구문 강조 지원이있는 간단한 Markdown 편집기를 제공하는 것을 목표로합니다. 이것은 textarea acapsulation을 기반으로하므로 ACS, Codemirror, Monaco 등과 같은 최신 코드 편집기에 의존하지 않습니다.
textarea 캡슐화를 기반으로하는 ♻️은 현대 코드 편집기에 의존하지 않습니다.uiw 구성 요소 라이브러리에 의존하지 않습니다.npm i @uiw/react-md-editor또는
yarn add @uiw/react-md-editor import React from "react" ;
import MDEditor from '@uiw/react-md-editor' ;
export default function App ( ) {
const [ value , setValue ] = React . useState ( "**Hello world!!!**" ) ;
return (
< div className = "container" >
< MDEditor
value = { value }
onChange = { setValue }
/>
< MDEditor . Markdown source = { value } style = { { whiteSpace : 'pre-wrap' } } />
</ div >
) ;
}CSS 스타일을 지원합니다
HTML 주석 <!--rehype:xxx--> 사용하여 Markdown이 스타일 사용자 정의를 지원하도록하십시오.
## Title
<!-- rehype:style=display: flex; height: 230px; align-items: center; justify-content: center; font-size: 38px; -->
Markdown Supports ** Style ** <!-- rehype:style=color: red; -->HTML 주석을 통해 컨텐츠 표시를 무시하십시오
HTML에서 제외 된 Github Readme에 표시됩니다.
# Hello World
<!-- rehype:ignore:start --> Hello World <!-- rehype:ignore:end -->
Good!산출:
< h1 > Hello World </ h1 >
< p > Good! </ p >저자를 완전히 신뢰 하지 않으면 Markdown을 소독해야합니다. 그렇지 않으면 앱이 XSS에 취약합니다. 이는 Rehype-Sanitize를 플러그인으로 추가하여 달성 할 수 있습니다.
import React from "react" ;
import MDEditor from '@uiw/react-md-editor' ;
import rehypeSanitize from "rehype-sanitize" ;
export default function App ( ) {
const [ value , setValue ] = React . useState ( `**Hello world!!!** <IFRAME SRC="javascript:javascript:alert(window.origin);"></IFRAME>` ) ;
return (
< div className = "container" >
< MDEditor
value = { value }
onChange = { setValue }
previewOptions = { {
rehypePlugins : [ [ rehypeSanitize ] ] ,
} }
/>
</ div >
) ;
} 다음 예제는 번들에 포함되지 않도록 코드 강조 코드를 제외하는 데 도움이 될 수 있습니다. @uiw/react-md-editor/nohighlight 구성 요소에는 포함되지 않습니다 코드 강조 표시 패키지,rehype-prism-plus ,,,highlightEnable 그리고showLineNumbers 기능은 더 이상 작동하지 않습니다. (#586) highlight line
import React from "react" ;
import MDEditor from '@uiw/react-md-editor/nohighlight' ;
const code = `**Hello world!!!**
```js
function demo() {}
```
`
export default function App ( ) {
const [ value , setValue ] = React . useState ( code ) ;
return (
< div className = "container" >
< MDEditor
value = { value }
onChange = { setValue }
/>
< MDEditor . Markdown source = { value } style = { { whiteSpace : 'pre-wrap' } } />
</ div >
) ;
} "아래는 편집기의 placeholder 설정하고 최대 입력 문자 길이를 10 자로 정의하는 예입니다."
import React from "react" ;
import MDEditor from '@uiw/react-md-editor' ;
export default function App ( ) {
const [ value , setValue ] = React . useState ( "" ) ;
return (
< MDEditor
value = { value }
onChange = { setValue }
textareaProps = { {
placeholder : 'Please enter Markdown text' ,
maxLength : 10
} }
/>
) ;
} import React , { useState } from "react" ;
import MDEditor , { commands } from '@uiw/react-md-editor' ;
const title3 = {
name : 'title3' ,
keyCommand : 'title3' ,
buttonProps : { 'aria-label' : 'Insert title3' } ,
icon : (
< svg width = "12" height = "12" viewBox = "0 0 520 520" >
< path fill = "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 ) => {
let modifyText = `### ${ state . selectedText } n` ;
if ( ! state . selectedText ) {
modifyText = `### ` ;
}
api . replaceSelection ( modifyText ) ;
} ,
} ;
const title2 = {
name : 'title2' ,
keyCommand : 'title2' ,
render : ( command , disabled , executeCommand ) => {
return (
< button
aria-label = "Insert title2"
disabled = { disabled }
onClick = { ( evn ) => {
// evn.stopPropagation();
executeCommand ( command , command . groupName )
} }
>
< svg width = "12" height = "12" viewBox = "0 0 520 520" >
< path fill = "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 ) => {
let modifyText = `## ${ state . selectedText } n` ;
if ( ! state . selectedText ) {
modifyText = `## ` ;
}
api . replaceSelection ( modifyText ) ;
} ,
}
function SubChildren ( { close , execute , getState , textApi , dispatch } ) {
const [ value , setValue ] = useState ( '' )
const insert = ( ) => {
console . log ( 'value:::' , value )
textApi . replaceSelection ( value )
}
return (
< div style = { { width : 120 , padding : 10 } } >
< div > My Custom Toolbar </ div >
< input type = "text" onChange = { ( e ) => setValue ( e . target . value ) } />
< button
type = "button"
onClick = { ( ) => {
dispatch ( { $value : '~~~~~~' } )
console . log ( '> execute: >>>>>' , getState ( ) )
} }
>
State
</ button >
< button type = "button" onClick = { insert } > Insert </ button >
< button type = "button" onClick = { ( ) => close ( ) } > Close </ button >
< button type = "button" onClick = { ( ) => execute ( ) } > Execute </ button >
</ div >
) ;
}
const subChild = {
name : 'update' ,
groupName : 'update' ,
icon : (
< svg viewBox = "0 0 1024 1024" width = "12" height = "12" >
< path fill = "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' }
}
export default function App ( ) {
const [ value , setValue ] = React . useState ( "Hello Markdown! `Tab` key uses default behavior" ) ;
return (
< div className = "container" >
< MDEditor
value = { value }
onChange = { setValue }
commands = { [
// Custom Toolbars
title3 , 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 >
) ;
} commands 및 extraCommands 소품으로 도구 모음을 사용자 정의하십시오.
import React from "react" ;
import MDEditor , { commands } from '@uiw/react-md-editor' ;
export default function App ( ) {
const [ value , setValue ] = React . useState ( "Hello Markdown! `Tab` key uses default behavior" ) ;
return (
< div className = "container" >
< MDEditor
value = { 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 : (
< svg viewBox = "0 0 1024 1024" width = "12" height = "12" >
< path fill = "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 (
< div style = { { width : 120 , padding : 10 } } >
< div > My Custom Toolbar </ div >
< button type = "button" onClick = { ( ) => console . log ( '> execute: >>>>>' , getState ( ) ) } > State </ button >
< button type = "button" onClick = { ( ) => close ( ) } > Close </ button >
< button type = "button" onClick = { ( ) => execute ( ) } > Execute </ button >
</ div >
) ;
} ,
execute : ( state , api ) => {
console . log ( '>>>>>>update>>>>>' , state )
} ,
buttonProps : { 'aria-label' : 'Insert title' }
} ) ,
commands . divider , commands . fullscreen
] }
/>
</ div >
) ;
} 리더 렌더 toolbar 요소.
import React from "react" ;
import MDEditor , { commands } from '@uiw/react-md-editor' ;
export default function App ( ) {
const [ value , setValue ] = React . useState ( "Hello Markdown! `Tab` key uses default behavior" ) ;
return (
< div className = "container" >
< MDEditor
value = { value }
onChange = { setValue }
preview = "edit"
components = { {
toolbar : ( command , disabled , executeCommand ) => {
if ( command . keyCommand === 'code' ) {
return (
< button
aria-label = "Insert code"
disabled = { disabled }
onClick = { ( evn ) => {
evn . stopPropagation ( ) ;
executeCommand ( command , command . groupName )
} }
>
Code
</ button >
)
}
}
} }
/>
</ div >
) ;
}사용자 정의 미리보기 명령 도구
import React , { useContext } from "react" ;
import MDEditor , { commands , EditorContext } from "@uiw/react-md-editor" ;
const Button = ( ) => {
const { preview , dispatch } = useContext ( EditorContext ) ;
const click = ( ) => {
dispatch ( {
preview : preview === "edit" ? "preview" : "edit"
} ) ;
} ;
if ( preview === "edit" ) {
return (
< svg width = "12" height = "12" viewBox = "0 0 520 520" onClick = { click } >
< polygon
fill = "currentColor"
points = "0 71.293 0 122 319 122 319 397 0 397 0 449.707 372 449.413 372 71.293"
/>
< polygon
fill = "currentColor"
points = "429 71.293 520 71.293 520 122 481 123 481 396 520 396 520 449.707 429 449.413"
/>
</ svg >
) ;
}
return (
< svg width = "12" height = "12" viewBox = "0 0 520 520" onClick = { click } >
< polygon
fill = "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"
/>
< polygon
fill = "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 >
) ;
} ;
const codePreview = {
name : "preview" ,
keyCommand : "preview" ,
value : "preview" ,
icon : < Button />
} ;
const Disable = ( ) => {
const { preview , dispatch } = useContext ( EditorContext ) ;
return (
< button disabled = { preview === "preview" } >
< svg viewBox = "0 0 16 16" width = "12px" height = "12px" >
< path
d = "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 >
)
}
const customButton = {
name : "disable" ,
keyCommand : "disable" ,
value : "disable" ,
icon : < Disable />
}
export default function App ( ) {
const [ value , setValue ] = React . useState ( "**Hello world!!!**" ) ;
return (
< div className = "container" >
< div > The system automatically sets the theme </ div >
< MDEditor
value = { value }
preview = "edit"
extraCommands = { [ codePreview , customButton , commands . fullscreen ] }
onChange = { ( val ) => setValue ( val ) }
/>
</ div >
) ;
}도움말 명령 도구를 추가하십시오
import React , { useContext } from "react" ;
import MDEditor , { commands } from "@uiw/react-md-editor" ;
const help = {
name : "help" ,
keyCommand : "help" ,
buttonProps : { "aria-label" : "Insert help" } ,
icon : (
< svg viewBox = "0 0 16 16" width = "12px" height = "12px" >
< path
d = "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" ) ;
}
} ;
export default function App ( ) {
const [ value , setValue ] = React . useState ( "**Hello world!!!**" ) ;
return (
< MDEditor
value = { value }
preview = "edit"
commands = { [ ... commands . getCommands ( ) , help ] }
onChange = { ( val ) => setValue ( val ) }
/>
) ;
} 국제화 예, 국제화를 위해 commands-cn 을 참조 할 수 있습니다.
import React , { useContext } from "react" ;
import MDEditor , { commands } from "@uiw/react-md-editor" ;
import { getCommands , getExtraCommands } from "@uiw/react-md-editor/commands-cn" ;
export default function App ( ) {
const [ value , setValue ] = React . useState ( "**Hello world!!!**" ) ;
return (
< MDEditor
value = { 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 : 23 px !important ;
line-height : 24 px !important ;
} 초기 높이는 minHeight={100} 통해 조정할 수 있습니다. Dragbar는 자동으로 만료됩니다. visibleDragbar={false} 를 통해 드래그 버튼을 숨길 수 있습니다.
import React from "react" ;
import MDEditor from '@uiw/react-md-editor' ;
export default function App ( ) {
const [ value , setValue ] = React . useState ( "**Hello world!!!**" ) ;
return (
< div className = "container" >
< MDEditor
value = { value }
height = "100%"
// minHeight={50}
visibleDragbar = { false }
onChange = { setValue }
/>
</ div >
) ;
} import React from "react" ;
import MDEditor from '@uiw/react-md-editor' ;
export default function App ( ) {
const [ value , setValue ] = React . useState ( "**Hello world!!!** <style>body{display:none;}</style> " ) ;
return (
< div className = "container" >
< MDEditor
value = { value }
height = "100%"
previewOptions = { {
disallowedElements : [ 'style' ] ,
} }
visibleDragbar = { false }
onChange = { setValue }
/>
</ div >
) ;
} import React from "react" ;
import MDEditor from '@uiw/react-md-editor' ;
export default function App ( ) {
return (
< div className = "container" >
< MDEditor . Markdown source = "Hello Markdown!" />
</ div >
) ;
} Katex는 웹에서 Tex 수학 렌더링을위한 빠르고 사용하기 쉬운 JavaScript 라이브러리이며 KaTeX 통해 수학 렌더링을 수행합니다.
다음 예제는 Codesandbox에서 미리보기입니다.
켈 V2를 V3 D025430으로 업그레이드하십시오
npm install katex import React from "react" ;
import MDEditor from '@uiw/react-md-editor' ;
import { getCodeString } from 'rehype-rewrite' ;
import katex from 'katex' ;
import 'katex/dist/katex.css' ;
const mdKaTeX = `This is to display the
`$$c = \pm\sqrt{a^2 + b^2}$$`
in one line
```KaTeX
c = \pm\sqrt{a^2 + b^2}
```
` ;
export default function App ( ) {
const [ value , setValue ] = React . useState ( mdKaTeX ) ;
return (
< MDEditor
value = { value }
onChange = { ( val ) => setValue ( val ) }
previewOptions = { {
components : {
code : ( { children = [ ] , className , ... props } ) => {
if ( typeof children === 'string' && / ^$$(.*)$$ / . test ( children ) ) {
const html = katex . renderToString ( children . replace ( / ^$$(.*)$$ / , '$1' ) , {
throwOnError : false ,
} ) ;
return < code dangerouslySetInnerHTML = { { __html : html } } style = { { background : 'transparent' } } /> ;
}
const code = props . node && props . node . children ? getCodeString ( props . node . children ) : children ;
if (
typeof code === 'string' &&
typeof className === 'string' &&
/ ^language-katex / . test ( className . toLocaleLowerCase ( ) )
) {
const html = katex . renderToString ( code , {
throwOnError : false ,
} ) ;
return < code style = { { fontSize : '150%' } } dangerouslySetInnerHTML = { { __html : html } } /> ;
}
return < code className = { String ( className ) } > { children } </ code > ;
} ,
} ,
} }
/>
) ;
} import React , { useState } from "react" ;
import MDEditor , { commands , ICommand , TextState , TextAreaTextApi } from "@uiw/react-md-editor" ;
import domToImage from "dom-to-image" ;
const textToImage : ICommand = {
name : "Text To Image" ,
keyCommand : "text2image" ,
buttonProps : { "aria-label" : "Insert title3" } ,
icon : (
< svg width = "12" height = "12" viewBox = "0 0 20 20" >
< path fill = "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 ) => {
const dom = document . getElementsByClassName ( "gooooooooo" ) [ 0 ] ;
if ( dom ) {
domToImage . toJpeg ( dom , { } ) . then ( ( dataUrl ) => {
const link = document . createElement ( "a" ) ;
link . download = "image.jpg" ;
link . href = dataUrl ;
link . click ( ) ;
} ) ;
}
}
} ;
export default function App ( ) {
const [ value , setValue ] = useState ( '**Hello world!!!**' ) ;
console . log ( 'value::' , value )
return (
< div className = "container" >
< MDEditor
className = "gooooooooo"
onChange = { ( newValue = "" ) => setValue ( newValue ) }
value = { value }
commands = { [
textToImage ,
commands . divider
] }
/>
</ div >
) ;
}Mermaid 사용 마크 다운과 유사한 방식으로 텍스트에서 다이어그램 및 유량 차트 생성까지
npm install mermaid import React , { useState , useRef , useEffect , Fragment , useCallback } from "react" ;
import MDEditor from "@uiw/react-md-editor" ;
import { getCodeString } from 'rehype-rewrite' ;
import mermaid from "mermaid" ;
const mdMermaid = `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.
```mermaid
graph TD
A[Hard] -->|Text| B(Round)
B --> C{Decision}
C -->|One| D[Result 1]
C -->|Two| E[Result 2]
```
```mermaid
sequenceDiagram
Alice->>John: Hello John, how are you?
loop Healthcheck
John->>John: Fight against hypochondria
end
Note right of John: Rational thoughts!
John-->>Alice: Great!
John->>Bob: How about you?
Bob-->>John: Jolly good!
```
` ;
const randomid = ( ) => parseInt ( String ( Math . random ( ) * 1e15 ) , 10 ) . toString ( 36 ) ;
const Code = ( { inline , children = [ ] , className , ... props } ) => {
const demoid = useRef ( `dome ${ randomid ( ) } ` ) ;
const [ container , setContainer ] = useState ( null ) ;
const isMermaid =
className && / ^language-mermaid / . test ( className . toLocaleLowerCase ( ) ) ;
const code = 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 ] ) ;
const refElement = useCallback ( ( node ) => {
if ( node !== null ) {
setContainer ( node ) ;
}
} , [ ] ) ;
if ( isMermaid ) {
return (
< Fragment >
< code id = { demoid . current } style = { { display : "none" } } />
< code className = { className } ref = { refElement } data-name = "mermaid" />
</ Fragment >
) ;
}
return < code className = { className } > { children } </ code > ;
} ;
export default function App ( ) {
const [ value , setValue ] = useState ( mdMermaid ) ;
return (
< MDEditor
onChange = { ( newValue = "" ) => setValue ( newValue ) }
textareaProps = { {
placeholder : "Please enter Markdown text"
} }
height = { 500 }
value = { value }
previewOptions = { {
components : {
code : Code
}
} }
/>
) ;
} 다음 JS에서 예제를 사용하십시오. #52 #224
npm install next-remove-imports
npm install @uiw/[email protected] // next.config.js
const removeImports = require ( 'next-remove-imports' ) ( ) ;
module . exports = removeImports ( { } ) ; import "@uiw/react-md-editor/markdown-editor.css" ;
import "@uiw/react-markdown-preview/markdown.css" ;
import dynamic from "next/dynamic" ;
import { useState } from "react" ;
import * as commands from "@uiw/react-md-editor/commands"
const MDEditor = dynamic (
( ) => import ( "@uiw/react-md-editor" ) ,
{ ssr : false }
) ;
function HomePage ( ) {
const [ value , setValue ] = useState ( "**Hello world!!!**" ) ;
return (
< div >
< MDEditor value = { value } onChange = { setValue } />
</ div >
) ;
}
export default HomePage ; 기본적으로 dark-mode 시스템에 따라 자동으로 전환됩니다. 수동으로 전환 해야하는 경우 본문의 data-color-mode="dark" 매개 변수를 설정하십시오.
< html data-color-mode =" dark " > document . documentElement . setAttribute ( 'data-color-mode' , 'dark' )
document . documentElement . setAttribute ( 'data-color-mode' , 'light' ) .wmde-markdown-var selector를 추가하여 사용자 정의 색상 변수를 상속합니다. data-color-mode="light" 로 테마 스타일을 설정합니다.
< div data-color-mode =" light " >
< div className =" wmde-markdown-var " > </ div >
< MDEditor source =" Hello World! " />
</ div >value: string : 마크 다운 값.onChange?: (value?: string, event?: React.ChangeEvent<HTMLTextAreaElement>, state?: ContextStore) : onChange 이벤트의 이벤트 핸들러.onHeightChange?: ((value?: CSSProperties['height'], oldValue?: CSSProperties['height'], state?: ContextStore) : 편집기 높이 변경 리스너.onStatistics?: (data: Statistics) => void; 통계 편집기의 일부 데이터.commands?: ICommand[] : 각각은 commands 속성을 포함하는 ICommand 의 배열입니다. 명령이 지정되지 않으면 기본값이 사용됩니다. 명령은 아래에 자세히 설명되어 있습니다.commandsFilter?: (command: ICommand, isExtra: boolean) => false | ICommand : 명령을 필터링하거나 수정하십시오.extraCommands?: ICommand[] : 도구 모음의 오른쪽에 표시됩니다.autoFocus?: true : Markdown Editor 초기화에 집중하는 데 사용될 수 있습니다.previewOptions?: ReactMarkdown.ReactMarkdownProps : 이것은 @uiw/react-markdown-preview 설정을 재설정합니다.textareaProps?: TextareaHTMLAttributes : textarea 관련 소품을 설정하십시오.renderTextarea?: (props, opts) => JSX.Element;@deprecated 사용하십시오renderTextareacomponents . Div를 사용하여 TextRea 또는 Re-Render Textarea를 대체하십시오. #193components : Render Textarea/Toolbar 요소. #419textarea Div를 사용하여 TextRea 또는 Re-Render Textarea를 대체합니다toolbar 기본 명령 요소를 대체합니다. toolbar < command[].renderpreview 미리보기. #429height?: number=200 : 편집기의 높이. 켈Dragbar height 매개 변수 백분율 일 때 유효하지 않습니다.visibleDragbar?: boolean=true : 드래그 앤 드롭 도구를 표시하십시오. 편집기의 높이를 설정하십시오.highlightEnable?: boolean=true : 편집 영역 코드 강조 표시를 비활성화합니다. 값은 false 이므로 편집 속도가 증가합니다.fullscreen?: boolean=false : 표시 마크 다운 미리보기.overflow?: boolean=true : fullscreen 설정 바디 스타일을 비활성화합니다preview?: 'live' | 'edit' | 'preview' : 기본값 live , 마크 다운 미리보기를 표시하십시오.maxHeight?: number=1200 : 최대 드래그 높이. visibleDragbar=true 값이 유효합니다.minHeight?: number=100 : 최소 드래그 높이. visibleDragbar=true 값이 유효합니다.tabSize?: number=2 : 탭 키를 누를 때 삽입 할 문자 수입니다. 기본 2 공간.defaultTabEnable?: boolean=false : false 인 경우 tab 키는 TAB 문자를 TextArea에 삽입합니다. true 경우 tab 키는 기본 동작을 실행합니다. 예를 들어 초점은 다음 요소로 이동합니다.hideToolbar?: boolean=false : 도구 막대를 숨기는 옵션.enableScroll?: boolean=true : 스크롤 활성화 여부.$ npm install # Installation dependencies
$ npm run build # Compile all package@uiw/react-md-editor 패키지 : $ 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`npm run start언제나 그렇듯이 놀라운 기고자 덕분에!
기고자와 함께 만들어졌습니다.
MIT 라이센스에 따라 라이센스.