Do you want to switch to Platzi in English?
Tu lugar en PlatziLive
Tu lugar en PlatziLive
estamos en vivo
12

Implementando Pulse Editor

20657Puntos

hace 2 años

En un pasado artículo presentamos Pulse Editor, el editor Markdown open source de Platzi. En esta ocasión quiero mostrarles como se puede implementar en un proyecto con React.js.

Iniciando el proyecto

Primero que todo vamos a iniciar el proyecto, para eso vamos a usar un simple comando:

yarn create next-app app

Eso (con la última versión de Yarn) nos va a crear un proyecto de Next.js en la carpeta app dejando todo listo para empezar a usarlo.

Otra opción sino es usar los siguientes comandos:

yarn init --yes
yarn add next react react-app

Ambos nos inician un proyecto con Next.js, aunque le primero nos crea varios archivos necesarios por Next.js por defecto. Entre ellos agrega los siguientes scripts al package.json.

{
	...
	"scripts": {
		"dev": "next dev",
		"build": "next build",
		"start": "next start"
	},
	...
}

Instalando Pulse Editor

Ahora que tenemos el proyecto vamos a instalar Pulse Editor, cosa que hacemos con Yarn.

yarn add pulse-editor

Eso nos instala Pulse Editor y lo agrega al package.json como dependencia. Con eso ya tenemos el editor instalado.

API del editor

Vamos a ver como funciona el API del editor. Es algo bastante sencillo, ya que simplemente nos exporta varios componentes que debemos combinar para armar nuestro editor.

import { Editor, ButtonBar, ButtonGroup, Field, Preview, EmojiBar } from'pulse-editor'

Ese es el primero grupo de componentes. Vamos a listar y describir cada uno:

  • <Editor /> -> Es el componente principal del editor, este debe envolver al resto de componentes para hacer funcionar al editor.
  • <ButtonBar /> -> Un componente muy simple que se usa para envolver los botones del editor, es un simple <div /> en realidad.
  • <ButtonGroup /> -> Al igual que el anterior, sirve para agrupar botones dentro de <ButtonBar />.
  • <Field /> -> Este componente renderiza el textarea del editor, se encarga de escuchar el evento change del mismo y enviar decirlo a <Editor /> que guarde el valor actual del editor. Además de eso implemente un autosize para que se agrande mientras más líneas escriba el usuario.
  • <Preview /> -> Este componente recibe el valor del <Field /> y lo parsea a HTML para mostrar la vista previa gracias a @platzi/react-markdown.
  • <EmojiBar /> -> Este componente renderiza una barra de sugerencias de emojis. Cuando el usuario escribe (al final del texto) : y dos caracteres muestra todos los emojis junto a su código (por ejemplo :thinking:) para que el usuario vea cuales existen y pueda hacer click sobre uno para seleccionarlo.

Estos son los componentes principales del editor y con esto armamos un editor, pero sin botones. Los botones vienen en un archivo y se importan de esta forma:

import {
	Base,
	Bold,
	Italic,
	Underline,
	Code,
	Link,
	Image,
	OrderedList,
	UnorderedList,
	Quote,
	Heading,
	Youtube,
} from'pulse-editor/buttons'

Estos son todos los botones que Pulse Editor nos provee por defecto. En general todos son muy fáciles de entender que hacen, el importante a destacar es <Base />. Este es solo la UI de un botón, no hace nada sobre el contenido y nos sirve para implementar nuestros propios botones usando la misma UI que los nativos de Pulse Editor. ¡De esta forma podemos crear todos los botones personalizados que necesitemos!

Implementación

Ahora sí: ¡manos a la obra!. Vamos a implementar el editor en nuestro proyecto. Para eso vamos a crear un archivo pages/index.js y a colocar este código.

import { Component } from'react'import { Editor, ButtonBar, ButtonGroup, Field, Preview, EmojiBar } from'pulse-editor'import { Bold, Italic, Underline } from'pulse-editor/buttons'exportdefault () => (
	<Editor>
		<ButtonBar>
			<ButtonGroup>
				<Bold><i className="fa fa-bold" /></Bold>
				<Italic><i className="fa fa-italic" /></Italic>
				<Underline><i className="fa fa-underline" /></Underline>
			</ButtonGroup>
		</ButtonBar>
		<div className="PulseEditor-content">
			<Field>
			<Preview />
		</div>
		<EmojiBar />
	</Editor>
)

Con eso ya tenemos nuestro editor list y funcionando. Esto nos debe mostrar todos los botones uno al lado de otro, luego el campo de texto, la vista previa (cuando se empiece a escribir) y si el usuario escribe un emoji entonces la barra de emojis.

¿Super simple no? Los botones al momento de montarse en la UI (componentDidMount) definen un atajo de teclado en el editor, así cuando usemos el atajo cmd+b o ctrl+b se va a usar Bold.

No todos los botones nativos definen atajos de teclado, algunos como <Code /> no definen ninguno y la única forma de usarlo es mediante el click manual.

Ahora eso muestra un editor super simple, sin estilos, para el CSS entonces vamos a cargar una archivo .css desde Github, para eso modificamos el código de nuestra página de esta forma:

import { Component } from'react'import { Editor, ButtonBar, ButtonGroup, Field, Preview, EmojiBar } from'pulse-editor'import { Bold, Italic, Underline } from'pulse-editor/buttons'import Head from'next/head'exportdefault () => (
	<Editor>
		<Head>
			<link
				rel='stylesheet'
				href='https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css'
			/>
			<link
				rel='stylesheet'
				href='https://raw.githubusercontent.com/PlatziDev/pulse-editor/master/examples/full-usage/static/styles.css'
			/>
		</Head>
		<ButtonBar>
			<ButtonGroup>
				<Bold><i className="fa fa-bold" /></Bold>
				<Italic><i className="fa fa-italic" /></Italic>
				<Underline><i className="fa fa-underline" /></Underline>
			</ButtonGroup>
		</ButtonBar>
		<div className="PulseEditor-content">
			<Field>
			<Preview />
		</div>
		<EmojiBar />
	</Editor>
)

Listo, ahí agregamos al head de nuestra página los <link /> para cargar FontAwesome (para los íconos que usamos en nuestros botones) y luego cargamos un CSS con estilos para el player. Pueden revisar el archivo para ver un ejemplo de como estilizarlo, igual todos los componentes reciben un prop className para personalizar el nombre de clase. Esto permite usarlo con librerías de CSS in JS como styled-jsx de Next.js o styled-components o incluso con CSS Modules o CSS de toda la vida.


Con esto nuestro editor ya se ve sin problemas. Pero todavía no hace nada más que permitirnos escribir. Vamos a hacer que haga POST de un formulario.

import { Component } from'react'import { Editor, ButtonBar, ButtonGroup, Field, Preview, EmojiBar } from'pulse-editor'import { Bold, Italic, Underline } from'pulse-editor/buttons'import Head from'next/head'exportdefault () => (
	<form action="/save-post" method="POST">
		<Editor>
			<Head>
				<link
					rel='stylesheet'
					href='https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css'
				/>
				<link
					rel='stylesheet'
					href='https://raw.githubusercontent.com/PlatziDev/pulse-editor/master/examples/full-usage/static/styles.css'
				/>
			</Head>
			<ButtonBar>
				<ButtonGroup>
					<Bold><i className="fa fa-bold" /></Bold>
					<Italic><i className="fa fa-italic" /></Italic>
					<Underline><i className="fa fa-underline" /></Underline>
				</ButtonGroup>
			</ButtonBar>
			<div className="PulseEditor-content">
				<Field>
				<Preview />
			</div>
			<EmojiBar />
		</Editor>
		<button>Guardar</button>
	<form>
)

Listo, con eso envolvimos el editor en un <form /> normal y hasta le pusimos un <button>, ahora cuando el usuario envié el formulario se va a enviar recargar la página para hacer el POST a /save-post, nuestro backend entonces va a recibir un formulario con un campo llamado value que contiene el Markdown que el usuario escribió.

Así podemos usar el editor como parte de un formulario normal, de HTML. Algo interesante es que podríamos en una página web normal que no use React.js, renderizar el editor dentro de cualquier formulario y se va a enviar sin problemas. Así podríamos usar Pulse Editor fuera de una app React, capaz en una simple landings page.

Obviamente es posible escuchar el evento submit del formulario y enviarlo por AJAX, en este sentido no hay ninguna diferencia, para el formulario el editor es simplemente un <textarea> normal de HTML.

Conclusión

Con esto ya tenemos integrado el editor en una aplicación de React. Vimos que además es posible usarlo fuera de una aplicación de React y funciona como un form normal. Y ya que usamos Next.js comprobamos que se puede hacer server render del editor sin problemas.

En futuros artículos vamos a ver como empezar a extender el editor para agregar características nuevas o crear botones personalizados.

Sergio Daniel
Sergio Daniel
@sergiodxa

20657Puntos

hace 2 años

Todas sus entradas
Escribe tu comentario
+ 2