Saltar al contenido

Editor de Markdown

UIMarkdownEditor edita Markdown con Crepe y un modo código, y conserva los bytes de lo que no tocas.

UIMarkdownEditor va en su propio módulo, @meekojs/ui/editor, porque Crepe pesa 347 KB de JS en gzip: dentro del módulo principal sería un chunk de cualquier web. El JavaScript de Crepe se carga en el navegador, al montar el componente, y nunca entra en el bundle del servidor. Hasta entonces, el HTML del servidor pinta un marcador con la altura definitiva.

Instalación

Crepe y CodeMirror son dependencias opcionales de @meekojs/ui: una aplicación sin el módulo no las instala.

meeko.config.ts ts
// pnpm add @milkdown/crepe @milkdown/kit @codemirror/language @codemirror/view \
//   @codemirror/lang-javascript @codemirror/lang-html @codemirror/lang-css @codemirror/lang-json @lezer/highlight
// meeko.config.ts
export default defineMeekoConfig({
  modules: ['@meekojs/ui', '@meekojs/ui/editor'],
})

Uso

Contenido
Cargando el editor…

Modo visual: 142 caracteres.

meeko
<script lang="ts">
  const markdown = signal('# Título')
  const mode = signal<'visual' | 'code'>('visual')
</script>

<template>
  <UIMarkdownEditor label="Contenido" model="markdown" model:mode="mode" />
</template>

Guardado por bloques

Crepe serializa un documento en su propio formato, así que guardar su salida reescribiría tablas y líneas en blanco que nadie tocó. Por eso el modelo sólo cambia con una edición real, y entonces conserva los bytes del original fuera de los bloques editados.

  • Sin editar, model sigue siendo el texto recibido, byte a byte. Escribir y deshacer también.
  • Un bloque editado sale de Crepe. Una lista es un solo bloque.
  • El frontmatter nunca llega a Crepe: se conserva tal cual.
  • El evento espera a una pausa al escribir, y se adelanta al salir del editor, antes de que un clic en «guardar» lea el modelo.
  • Si un documento no casa bloque a bloque con su serialización, se abre en modo código con un aviso.

API

Propiedades de UIMarkdownEditor
Nombre Tipo / valor inicial Descripción
model Signal<string> El texto. Si el padre escribe otro, el editor vuelve a empezar con él.
model:mode Signal<visual | code> visual El modo.
label string Obligatoria. Etiqueta visible y nombre accesible.
id string id del área de texto del modo código.
readonly boolean false Se puede leer y seleccionar, pero no cambiar.
disabled boolean false Como readonly, y además se ve deshabilitado.
describedBy string id del texto que lo describe.
placeholder string Texto del documento vacío.
class string Clase de la raíz.

El snippet tools va en la barra, entre la etiqueta y el conmutador. La altura se fija con --ui-markdown-editor-height y el contenido se desplaza dentro. Sus textos, también los de los menús de Crepe, están en ui.messages.<idioma>.markdownEditor. splitMarkdownSource y createMarkdownSplicer se exportan de @meekojs/ui/editor, sin Crepe.

¿Te sirvió esta página?

Añadir un comentario

Se envía al elegir «Sí» o «No». Solo se guardan la página, tu respuesta y el comentario: ni cookies ni datos tuyos.

0 de 2000 caracteres