Un editor basado en React y Prosemirror que impulsa Outline y también se puede usar para mostrar contenido en modo de solo lectura. El editor es WYSIWYG e incluye herramientas de formato, al tiempo que conserva la capacidad de escribir atajos de Markdown en línea y generar Markdown sin formato. Vea el libro de cuentos de demostración en vivo .
Nota importante: este proyecto no pretende ser un editor de Markdown multiuso . Está diseñado para la base de conocimientos de Outline y, aunque otros pueden bifurcar o utilizar este paquete en sus propios productos, las decisiones de desarrollo se centran en las necesidades de Outline.
yarn add rich-markdown-editoro
npm install rich-markdown-editor Tenga en cuenta que los componentes react , react-dom y styled-components son dependencias entre pares requeridas .
import Editor from "rich-markdown-editor" ;
< Editor
defaultValue = "Hello world!"
/> Clona este repositorio y ejecuta Storybook con yarn start para ver una amplia variedad de ejemplos de uso.
id Una identificación única para este editor, utilizada para conservar la configuración en el almacenamiento local. Si no se pasa ninguna id , el editor utilizará de forma predeterminada el nombre de la ruta de ubicación.
defaultValueUna cadena de rebajas que representa el valor inicial del editor. Utilice esto para restaurar el contenido previamente guardado para que el usuario continúe editando.
value Una cadena de rebajas que representa el valor del editor. Utilice este accesorio para cambiar el valor del editor una vez montado; esto volverá a representar todo el editor y, como tal, solo es adecuado cuando también está en modo readOnly . No canalice el valor de onChange nuevamente a value , el editor mantiene su propio estado interno y esto resultará en efectos secundarios inesperados.
placeholderPermite anular el marcador de posición. El valor predeterminado es "Escribe algo bonito...".
readOnly Con readOnly establecido en false el editor está optimizado para la composición. Cuando true el editor se puede utilizar para mostrar contenido escrito previamente: los títulos ganan anclajes y se puede hacer clic en los enlaces.
readOnlyWriteCheckboxes Con readOnlyWriteCheckboxes configurado en true las casillas de verificación aún se pueden marcar o desmarcar como un caso especial, mientras que readOnly está configurado en true y, de lo contrario, el editor no se puede editar.
autoFocus Cuando se establece true junto con readOnly establecido en false , se enfoca automáticamente al final del documento.
maxLengthCuando se establece, se aplica una longitud máxima de caracteres en el documento, sin incluir la sintaxis de rebajas.
extensionsPermite pasar complementos de Prosemirror adicionales a la instancia de Prosemirror subyacente.
disableExtensions Lista de nombres de extensiones incluidas para deshabilitar. Elimina los elementos de menú y comandos correspondientes. Por ejemplo, establezca en ["em", "blockquote"] para desactivar el texto en cursiva y las comillas en bloque.
themePermite anular el tema incorporado para personalizar el editor; por ejemplo, use su propia fuente y colores de marca para que el editor se ajuste a su aplicación. Consulte el tema incorporado para ver un ejemplo de las claves que se deben proporcionar.
dictionaryPermite anular el diccionario de copia incorporado, por ejemplo, para internacionalizar el editor. Consulte el diccionario incorporado para ver un ejemplo de las claves que se deben proporcionar.
dark Con dark configurado en true el editor usará un tema oscuro predeterminado que está incluido. Vea la fuente aquí.
dir Predeterminado: auto
Controla la dirección del documento. Los valores posibles son:
ltr : el diseño del editor está optimizado para documentos LTR y el contenido está marcado explícitamente como LTR.rtl : el diseño del editor está optimizado para documentos RTL y el contenido está marcado explícitamente como RTL.auto : el navegador decide el diseño del editor en función del contenido del documento. tooltipUn componente de React que se incluirá alrededor de elementos que tienen una información sobre herramientas opcional. Puede usar esto para inyectar su propia biblioteca de información sobre herramientas en el editor; al componente se le pasarán los siguientes accesorios:
tooltip : un nodo React con el contenido de información sobre herramientasplacement : Enum top , bottom , left , rightchildren : el componente que envuelve la información sobre herramientas debe representarse headingsOffset Un número que compensará los encabezados del documento en varios niveles. Por ejemplo, si ya anida el editor bajo un título h1 principal, es posible que desee que el usuario solo pueda crear encabezados h2 e inferiores; en este caso, establecería el accesorio en 1 .
scrollToUna cadena que representa un ancla de encabezado: el documento se desplazará suavemente para que el encabezado sea visible en la ventana gráfica.
embeds Opcionalmente, defina incrustaciones que se insertarán en lugar de enlaces cuando la función matcher devuelva un valor verdadero. El valor de retorno del método de comparación estará disponible en el componente en props.attrs.matches . Si se proporcionan title y icon , la inserción también aparecerá en el menú de bloqueo.
< Editor
embeds = { [
{
title : "Google Doc" ,
keywords : "google docs gdocs" ,
icon : < GoogleDocIcon /> ,
defaultHidden : false ,
matcher : href => href . matches ( / docs.google.com / i ) ,
component : GoogleDocEmbed
}
] }
/>uploadImage(file: Blob): Promise<string> Si desea que el editor admita imágenes, debe proporcionar esta devolución de llamada. La devolución de llamada debe aceptar un único objeto File y devolver una promesa que se resuelve en una URL cuando la imagen se ha cargado en una ubicación de almacenamiento, por ejemplo, S3. p.ej:
< Editor
uploadImage = { async file => {
const result = await s3 . upload ( file ) ;
return result . url ;
} }
/> onBlur(): void Esta devolución de llamada se activa cuando el usuario pierde el foco en el editor contenteditable y en todos los elementos de la interfaz de usuario asociados, como el menú de bloqueo y las barras de herramientas flotantes. Si desea escuchar eventos de desenfoque solo en el área de contenido, utilice los accesorios handleDOMEvents .
onFocus(): void Esta devolución de llamada se activa cuando el usuario se concentra en el editor contenteditable o en cualquier elemento de la interfaz de usuario asociado, como el menú de bloqueo o las barras de herramientas flotantes. Si desea escuchar eventos de enfoque solo en el área de contenido, utilice los accesorios handleDOMEvents .
onSave({ done: boolean }): void Esta devolución de llamada se activa cuando el usuario solicita explícitamente guardar usando un método abreviado de teclado, Cmd+S o Cmd+Enter . Puede utilizar esto como señal para guardar el documento en un servidor remoto.
onCancel(): void Esta devolución de llamada se activa cuando se presiona Cmd+Escape dentro del editor. Puede usarlo para cancelar la edición.
onChange(() => value): voidEsta devolución de llamada se activa cuando cambia el contenido del editor, generalmente debido a la entrada del usuario, como la pulsación de una tecla o el uso de opciones de formato. Puede usar esto para conservar localmente el estado de los editores.
Devuelve una función que, cuando se llama, devuelve el valor de texto actual del documento. Esta optimización se realiza para evitar serializar el estado del documento en texto en cada evento de cambio, lo que permite que la aplicación host elija cuándo necesita el valor serializado.
onImageUploadStart(): void Esta devolución de llamada se activa antes de uploadImage y se puede usar para mostrar alguna interfaz de usuario que indique que hay una carga en progreso.
onImageUploadStop(): voidSe activa una vez que la carga de una imagen se realizó correctamente o falló.
onSearchLink(term: string): Promise<{ title: string, subtitle?: string, url: string }[]>El editor ofrece la posibilidad de buscar enlaces para insertar desde la barra de herramientas de formato. Si se proporciona esta devolución de llamada, debería aceptar un término de búsqueda como único parámetro y devolver una promesa que se resuelva en una matriz de objetos. p.ej:
< Editor
onSearchLink = { async searchTerm => {
const results = await MyAPI . search ( searchTerm ) ;
return results . map ( result => {
title : result . name ,
subtitle : `Created ${ result . createdAt } ` ,
url : result . url
} )
} }
/> onCreateLink(title: string): Promise<string>El editor ofrece la posibilidad de crear enlaces desde la barra de herramientas de formato para la creación de documentos sobre la marcha. Si se proporciona esta devolución de llamada, debe aceptar un "título" del enlace como único parámetro y devolver una promesa que se resuelva en una URL para el enlace creado, por ejemplo:
< Editor
onCreateLink = { async title => {
const url = await MyAPI . create ( {
title
} ) ;
return url ;
} }
/> onShowToast(message: string, type: ToastType): void Se activa cuando el editor desea mostrar un mensaje al usuario. Conéctese al sistema de notificación de su aplicación o use de manera simplista window.alert(message) . El segundo parámetro es el tipo de brindis: 'error' o 'información'.
onClickLink(href: string, event: MouseEvent): void Esta devolución de llamada permite anular el manejo de enlaces. A menudo se da el caso de que desee que los enlaces externos abran una nueva ventana y que los enlaces internos utilicen algo como react-router para navegar. Si no se proporciona ninguna devolución de llamada, el comportamiento predeterminado de abrir una nueva pestaña se aplicará a todos los enlaces. p.ej:
import { history } from "react-router" ;
< Editor
onClickLink = { ( href , event ) => {
if ( isInternalLink ( href ) ) {
history . push ( href ) ;
} else {
window . location . href = href ;
}
} }
/> onHoverLink(event: MouseEvent): booleanEsta devolución de llamada permite detectar cuando el usuario pasa el cursor sobre un enlace del documento.
< Editor
onHoverLink = { event => {
console . log ( `Hovered link ${ event . target . href } ` ) ;
} }
/> onClickHashtag(tag: string, event: MouseEvent): voidEsta devolución de llamada permite el manejo de hacer clic en hashtags en el texto del documento. Si no se proporciona ninguna devolución de llamada, los hashtags se mostrarán como texto normal, por lo que puedes elegir si los admites o no pasando este accesorio.
import { history } from "react-router" ;
< Editor
onClickHashtag = { tag => {
history . push ( `/hashtags/ ${ tag } ` ) ;
} }
/> handleDOMEvents: {[name: string]: (view: EditorView, event: Event) => boolean;} Este objeto asigna nombres de eventos ( focus , paste , touchstart , etc.) a funciones de devolución de llamada.
< Editor
handleDOMEvents = { {
focus : ( ) => console . log ( "FOCUS" ) ,
blur : ( ) => console . log ( "BLUR" ) ,
paste : ( ) => console . log ( "PASTE" ) ,
touchstart : ( ) => console . log ( "TOUCH START" ) ,
} }
/>El componente Editor expone algunos métodos para interactuar con el editor montado.
focusAtStart(): voidColoque el cursor al inicio del documento y enfóquelo.
focusAtEnd(): voidColoque el cursor al final del documento y enfóquelo.
getHeadings(): { title: string, level: number, id: string }[] Devuelve una matriz de objetos con el contenido de texto de todos los encabezados del documento, su nivel en la jerarquía y la identificación del ancla. Esto es útil para construir su propia tabla de contenido ya que la opción toc se eliminó en v10.
Este proyecto utiliza hilo para gestionar las dependencias. Puede usar npm, sin embargo, no respetará el archivo de bloqueo de hilo y puede instalar versiones ligeramente diferentes.
yarn install
Cuando se ejecuta en desarrollo, Storybook se incluye en editores de ejemplo con recarga en caliente. Después de instalar las dependencias, ejecute yarn start a funcionar.
Al desarrollar usando yarn link , puede usar yarn watch para reconstruir continuamente los cambios en dist a medida que realiza cambios.
Este proyecto tiene licencia BSD.