Reacto de componente Wrapper para Easymde (o garfo mais fresco SimpleMde).
Apenas duas dependências, React (par) e Easymde (par).
Construído por @rip21?
easymde , codemirror ou cursor para poder manipulá -las.Índice gerado com o Markdown-Toc
>=16.8.2easymde agora uma dependência de colegas, instale -a manualmentelabel foi removidaoptions devem ser memorizadas para impedir que novas instâncias sejam criadas em cada renderização e outras relacionadas a esses bugs (mais sobre isso abaixo)ref , para que você possa facilmente ter acesso ao div Wrapper usando ref Prop.@babel/runtime Helders não estão mais inlinados, mas importados. npm install --save react-simplemde-editor easymde
Nota: Possivelmente, pode ser necessário instalar @babel/runtime , tente sem ele, mas se você não tiver nenhum problema, não deve.
Demonstração hospedada
ou para vê -lo localmente:
git clone https://github.com/RIP21/react-simplemde-editor.git
cd react-simplemde-editor
yarn install
yarn demo
open browser at localhost:3000
Veja o código de demonstração para obter mais exemplos.
Todos os exemplos abaixo estão no TypeScript
Uso não controlado
import React from "react" ;
import SimpleMDE from "react-simplemde-editor" ;
import "easymde/dist/easymde.min.css" ;
< SimpleMDE /> ; export const ControlledUsage = ( ) => {
const [ value , setValue ] = useState ( "Initial value" ) ;
const onChange = useCallback ( ( value : string ) => {
setValue ( value ) ;
} , [ ] ) ;
return < SimpleMdeReact value = { value } onChange = { onChange } /> ;
} ; Você pode definir a API de opções simples que você passa como um suporte options . Se você estiver usando o TypeScript, ele será inferido pelo compilador.
Nota: Se você não especificar um ID personalizado, ele gerará automaticamente um ID para você.
Observe que você precisa useMemo options de memórias para que elas não mudem em cada reprodução! Isso afetará o comportamento e o desempenho, pois, em cada renderização dos pais, que torna SimpleMdeReact você receberá uma nova instância do editor, que você definitivamente deseja evitar! Além disso, se você alterar options em cada alteração value , perderá o foco. Portanto, coloque options como uma const fora do componente ou se options devem ser parcial ou totalmente definidas por props , certifique -se de useMemo em caso de componentes funcionais/ganchos, ou campo de classe para componentes baseados em class . Um pouco mais sobre isso aqui: #164
export const UsingOptions = ( ) => {
const [ value , setValue ] = useState ( "Initial" ) ;
const onChange = useCallback ( ( value : string ) => {
setValue ( value ) ;
} , [ ] ) ;
const autofocusNoSpellcheckerOptions = useMemo ( ( ) => {
return {
autofocus : true ,
spellChecker : false ,
} as SimpleMDE . Options ;
} , [ ] ) ;
return (
< SimpleMdeReact
options = { autofocusNoSpellcheckerOptions }
value = { value }
onChange = { onChange }
/>
) ;
} ; Você pode incluir mapas de chaves usando o suporte extraKeys . Leia mais no Codemirror Teclas Extra
export const UpdateableByHotKeys = ( ) => {
const extraKeys = useMemo < KeyMap > ( ( ) => {
return {
Up : function ( cm ) {
cm . replaceSelection ( " surprise. " ) ;
} ,
Down : function ( cm ) {
cm . replaceSelection ( " surprise again! " ) ;
} ,
} ;
} , [ ] ) ;
const [ value , setValue ] = useState ( "initial" ) ;
const onChange = ( value : string ) => setValue ( value ) ;
return (
< SimpleMdeReact value = { value } onChange = { onChange } extraKeys = { extraKeys } />
) ;
} ; import ReactDOMServer from "react-dom/server" ;
export const CustomPreview = ( ) => {
const customRendererOptions = useMemo ( ( ) => {
return {
previewRender ( ) {
return ReactDOMServer . renderToString (
< ReactMarkdown
source = { text }
renderers = { {
CodeBlock : CodeRenderer ,
Code : CodeRenderer ,
} }
/>
) ;
} ,
} as SimpleMDE . Options ;
} , [ ] ) ;
return (
< div >
< h4 > Custom preview </ h4 >
< SimpleMdeReact options = { customRendererOptions } />
</ div >
) ;
} ;Veja a lista completa de eventos aqui
import { SimpleMdeReact } from "react-simplemde-editor" ;
import type { SimpleMdeToCodemirrorEvents } from "react-simplemde-editor" ;
export const CustomEventListeners = ( ) => {
const [ value , setValue ] = useState ( "Initial value" ) ;
const onChange = useCallback ( ( value : string ) => {
setValue ( value ) ;
} , [ ] ) ;
// Make sure to always `useMemo` all the `options` and `events` props to ensure best performance!
const events = useMemo ( ( ) => {
return {
focus : ( ) => console . log ( value ) ,
} as SimpleMdeToCodemirrorEvents ;
} , [ ] ) ;
return < SimpleMdeReact events = { events } value = { value } onChange = { onChange } /> ;
} ; export const Autosaving = ( ) => {
const delay = 1000 ;
const autosavedValue = localStorage . getItem ( `smde_demo` ) || "Initial value" ;
const anOptions = useMemo ( ( ) => {
return {
autosave : {
enabled : true ,
uniqueId : "demo" ,
delay ,
} ,
} ;
} , [ delay ] ) ;
return (
< SimpleMdeReact id = "demo" value = { autosavedValue } options = { anOptions } />
) ;
} ;easymde , codemirror ou cursor para poder manipulá -las. export const GetDifferentInstances = ( ) => {
// simple mde
const [ simpleMdeInstance , setMdeInstance ] = useState < SimpleMDE | null > ( null ) ;
const getMdeInstanceCallback = useCallback ( ( simpleMde : SimpleMDE ) => {
setMdeInstance ( simpleMde ) ;
} , [ ] ) ;
useEffect ( ( ) => {
simpleMdeInstance &&
console . info ( "Hey I'm editor instance!" , simpleMdeInstance ) ;
} , [ simpleMdeInstance ] ) ;
// codemirror
const [ codemirrorInstance , setCodemirrorInstance ] = useState < Editor | null > (
null
) ;
const getCmInstanceCallback = useCallback ( ( editor : Editor ) => {
setCodemirrorInstance ( editor ) ;
} , [ ] ) ;
useEffect ( ( ) => {
codemirrorInstance &&
console . info ( "Hey I'm codemirror instance!" , codemirrorInstance ) ;
} , [ codemirrorInstance ] ) ;
// line and cursor
const [ lineAndCursor , setLineAndCursor ] = useState < Position | null > ( null ) ;
const getLineAndCursorCallback = useCallback ( ( position : Position ) => {
setLineAndCursor ( position ) ;
} , [ ] ) ;
useEffect ( ( ) => {
lineAndCursor &&
console . info ( "Hey I'm line and cursor info!" , lineAndCursor ) ;
} , [ lineAndCursor ] ) ;
return (
< div >
< h4 > Getting instance of Mde and codemirror and line and cursor info </ h4 >
< SimpleMdeReact
value = "Go to console to see stuff logged"
getMdeInstance = { getMdeInstanceCallback }
getCodemirrorInstance = { getCmInstanceCallback }
getLineAndCursor = { getLineAndCursorCallback }
/>
</ div >
) ;
} ;Aqui está como você faz isso. Requer zombar de certas peças do navegador funcionar, mas esse é todo o exemplo.
import { act , render , screen } from "@testing-library/react" ;
import { useState } from "react" ;
import { SimpleMdeReact } from "react-simplemde-editor" ;
import userEvent from "@testing-library/user-event" ;
// @ts-ignore
Document . prototype . createRange = function ( ) {
return {
setEnd : function ( ) { } ,
setStart : function ( ) { } ,
getBoundingClientRect : function ( ) {
return { right : 0 } ;
} ,
getClientRects : function ( ) {
return {
length : 0 ,
left : 0 ,
right : 0 ,
} ;
} ,
} ;
} ;
const Editor = ( ) => {
const [ value , setValue ] = useState ( "" ) ;
return < SimpleMdeReact value = { value } onChange = { setValue } /> ;
} ;
describe ( "Renders" , ( ) => {
it ( "succesfully" , async ( ) => {
act ( ( ) => {
render ( < Editor /> ) ;
} ) ;
const editor = await screen . findByRole ( "textbox" ) ;
userEvent . type ( editor , "hello" ) ;
expect ( screen . getByText ( "hello" ) ) . toBeDefined ( ) ;
} ) ;
} ) ; export interface SimpleMDEReactProps
extends Omit < React . HTMLAttributes < HTMLDivElement > , "onChange" > {
id ?: string ;
onChange ?: ( value : string , changeObject ?: EditorChange ) => void ;
value ?: string ;
extraKeys ?: KeyMap ;
options ?: SimpleMDE . Options ;
events ?: SimpleMdeToCodemirrorEvents ;
getMdeInstance ?: GetMdeInstance ;
getCodemirrorInstance ?: GetCodemirrorInstance ;
getLineAndCursor ?: GetLineAndCursor ;
placeholder ?: string ;
textareaProps ?: Omit <
React . HTMLAttributes < HTMLTextAreaElement > ,
"id" | "style" | "placeholder"
> ;
} default - SimpleMeDeAct
SimpleMdeReact - o mesmo que default , mas nomeado
Tipos:
SimpleMdeReactProps - adereços do componente
DOMEvent - Certos eventos que são usados para obter eventos exportados abaixo
CopyEvents - Copie apenas eventos de codemirror
GlobalEvents - alguns outros eventos globais de codemirror
DefaultEvent - Função de manipulador de eventos Codemirror padrão
IndexEventsSignature - assinatura do índice que espera string como chave e DefaultEvent
SimpleMdeToCodemirrorEvents - Eventos trabalhados manualmente (baseados em @types/[email protected] que easymde usa internamente) + todos os itens acima se fundiram em mapeamento inteiro entre nomes de eventos Codemirror e manipuladores reais para events prop.
GetMdeInstance - assinatura da função de retorno de chamada que recupera a instância do MDE
GetCodemirrorInstance - assinatura da função de retorno de chamada que recupera a instância do codemirror
GetLineAndCursor - assinatura da função de retorno de chamada que recupera a linha e as informações do cursor
simplemde . Possíveis mudanças de ruptura, então eu coloquei a versão para V4.simplemde/dist/simplemde.min.css agora será easymde/dist/easymde.min.css initialValue foi removido e substituído por um suporte value , permitindo alterações diretas no valor a ser feito após o montagem do componente.A versão 1.0 não possuía opções simples configuradas bem, este ReadMe reflete as alterações feitas para melhor incluir opções. Este ainda é um projeto muito novo. Testes, feedback e PRs são bem -vindos e apreciados.