Un componente Quill para React.
Vea una demostración en vivo o Codepen.
Esta es la documentación para ReactQuill v2 - Versiones anteriores: v1
? Reaccionar Quill v2
¡ReactQuill 2 ya está aquí, cariño! Y trae una adaptación completa a TypeScript y React 16+, un sistema de compilación refactorizado y un ajuste general de la lógica interna.
Trabajamos duro para evitar introducir cambios de comportamiento. En la gran mayoría de los casos, no es necesaria ninguna migración. Sin embargo, se ha eliminado la compatibilidad con accesorios obsoletos desde hace mucho tiempo, ReactQuill Mixin y el componente de la barra de herramientas. Asegúrese de leer la guía de migración.
Esperamos que esta versión sea una actualización inmediata; si ese no es el caso, presente un problema con la etiqueta v2
.
Asegúrate de tener react
y react-dom
, y alguna forma de cargar estilos, como style-loader. Consulte la documentación sobre temas para obtener más información.
npm install react-quill --save
import React , { useState } from 'react' ;
import ReactQuill from 'react-quill' ;
import 'react-quill/dist/quill.snow.css' ;
function MyComponent ( ) {
const [ value , setValue ] = useState ( '' ) ;
return < ReactQuill theme = "snow" value = { value } onChange = { setValue } / > ;
}
< link
rel =" stylesheet "
href =" https://unpkg.com/[email protected]/dist/quill.snow.css "
/>
< script
src =" https://unpkg.com/react@16/umd/react.development.js "
crossorigin
> </ script >
< script
src =" https://unpkg.com/react-dom@16/umd/react-dom.development.js "
crossorigin
> </ script >
< script src =" https://unpkg.com/[email protected]/dist/react-quill.js " > </ script >
< script src =" https://unpkg.com/babel-standalone@6/babel.min.js " > </ script >
< script type =" text/babel " src =" /my-scripts.js " > </ script >
En modo controlado, se supone que los componentes evitan cambios de estado locales y, en cambio, solo ocurren a través de onChange
y value
.
Debido a que Quill maneja sus propios cambios y no permite impedir las ediciones, ReactQuill tiene que conformarse con un híbrido entre el modo controlado y no controlado. No puede evitar el cambio, pero aún así anulará el contenido siempre que value
difiera del estado actual.
Si necesita manipular el DOM con frecuencia o utilizar las API de Quill de manera imperativa, podría considerar cambiar al modo totalmente no controlado. ReactQuill inicializará el editor usando defaultValue
, pero no intentará restablecerlo después de eso. La devolución de llamada onChange
seguirá funcionando como se esperaba.
Lea más sobre componentes no controlados en los documentos de React.
Puede pasar un Quill Delta, en lugar de una cadena HTML, como las propiedades value
y defaultValue
. Los deltas tienen una serie de ventajas sobre las cadenas HTML, por lo que es posible que desee utilizarlos en su lugar. Sin embargo, tenga en cuenta que comparar deltas para cambios es más costoso que comparar cadenas HTML, por lo que podría valer la pena perfilar sus patrones de uso.
Tenga en cuenta que cambiar value
de una cadena HTML a un Delta, o viceversa, desencadenará un cambio, independientemente de si representan el mismo documento, por lo que es posible que desee ceñirse a un formato y seguir usándolo de manera consistente en todo momento.
delta
que recibe del evento onChange
como value
. Este objeto no contiene el documento completo, sino sólo las últimas modificaciones, y al hacerlo lo más probable es que se desencadene un bucle infinito donde se aplican los mismos cambios una y otra vez. Utilice editor.getContents()
durante el evento para obtener un Delta del documento completo. ReactQuill evitará que cometas ese error; sin embargo, si estás absolutamente seguro de que esto es lo que deseas, puedes pasar el objeto a través new Delta()
nuevamente para eliminarlo.
El editor Quill admite temas. Incluye un tema completo, llamado nieve , que es la apariencia estándar de Quill, y un tema de burbujas similar al editor en línea de Medium. Como mínimo, se debe incluir el tema principal para que funcionen módulos como barras de herramientas o información sobre herramientas.
Para activar un tema, pase el nombre del tema al accesorio theme
. Pase un valor falso (p. ej., null
) para utilizar el tema principal.
< ReactQuill theme = "snow" . . . / >
Luego, importe la hoja de estilo de los temas que desea utilizar.
Esto puede variar dependiendo de cómo esté estructurada la aplicación, directorios u otros. Por ejemplo, si utiliza un preprocesador de CSS como SASS, es posible que desee importar esa hoja de estilo dentro de la suya. Estas hojas de estilo se pueden encontrar en la distribución de Quill, pero por conveniencia también están vinculadas en la carpeta dist
de ReactQuill.
Aquí hay un ejemplo que usa style-loader para Webpack, o create-react-app
, que inyectará automáticamente los estilos en la página:
import 'react-quill/dist/quill.snow.css' ;
Los estilos también están disponibles a través de CDN:
< link
rel =" stylesheet "
href =" https://unpkg.com/[email protected]/dist/quill.snow.css "
/>
La API del módulo de barra de herramientas Quill proporciona una manera fácil de configurar los íconos predeterminados de la barra de herramientas usando una variedad de nombres de formato.
class MyComponent extends Component {
constructor ( props ) {
super ( props ) ;
this . state = {
text : "" ,
}
}
modules = {
toolbar : [
[ { 'header' : [ 1 , 2 , false ] } ] ,
[ 'bold' , 'italic' , 'underline' , 'strike' , 'blockquote' ] ,
[ { 'list' : 'ordered' } , { 'list' : 'bullet' } , { 'indent' : '-1' } , { 'indent' : '+1' } ] ,
[ 'link' , 'image' ] ,
[ 'clean' ]
] ,
} ,
formats = [
'header' ,
'bold' , 'italic' , 'underline' , 'strike' , 'blockquote' ,
'list' , 'bullet' , 'indent' ,
'link' , 'image'
] ,
render ( ) {
return (
< div className = "text-editor" >
< ReactQuill theme = "snow"
modules = { this . modules }
formats = { this . formats } >
< / ReactQuill >
< / div >
) ;
}
}
export default MyComponent ;
También puede proporcionar su propia barra de herramientas HTML/JSX con elementos personalizados que no forman parte del tema Quill.
Vea este ejemplo en vivo en Codepen: Ejemplo de barra de herramientas personalizada
/*
* Custom "star" icon for the toolbar using an Octicon
* https://octicons.github.io
*/
const CustomButton = ( ) => < span className = "octicon octicon-star" / > ;
/*
* Event handler to be attached using Quill toolbar module
* http://quilljs.com/docs/modules/toolbar/
*/
function insertStar ( ) {
const cursorPosition = this . quill . getSelection ( ) . index ;
this . quill . insertText ( cursorPosition , '★' ) ;
this . quill . setSelection ( cursorPosition + 1 ) ;
}
/*
* Custom toolbar component including insertStar button and dropdowns
*/
const CustomToolbar = ( ) => (
< div id = "toolbar" >
< select
className = "ql-header"
defaultValue = { '' }
onChange = { ( e ) => e . persist ( ) }
>
< option value = "1" > < / option >
< option value = "2" > < / option >
< option selected > < / option >
< / select >
< button className = "ql-bold" > < / button >
< button className = "ql-italic" > < / button >
< select className = "ql-color" >
< option value = "red" > < / option >
< option value = "green" > < / option >
< option value = "blue" > < / option >
< option value = "orange" > < / option >
< option value = "violet" > < / option >
< option value = "#d0d1d2" > < / option >
< option selected > < / option >
< / select >
< button className = "ql-insertStar" >
< CustomButton / >
< / button >
< / div >
) ;
/*
* Editor component with custom toolbar and content containers
*/
class Editor extends React . Component {
constructor ( props ) {
super ( props ) ;
this . state = { editorHtml : '' } ;
this . handleChange = this . handleChange . bind ( this ) ;
}
handleChange ( html ) {
this . setState ( { editorHtml : html } ) ;
}
render ( ) {
return (
< div className = "text-editor" >
< CustomToolbar / >
< ReactQuill
onChange = { this . handleChange }
placeholder = { this . props . placeholder }
modules = { Editor . modules }
/ >
< / div >
) ;
}
}
/*
* Quill modules to attach to editor
* See http://quilljs.com/docs/modules/ for complete options
*/
Editor . modules = {
toolbar : {
container : '#toolbar' ,
handlers : {
insertStar : insertStar ,
} ,
} ,
} ;
/*
* Quill editor formats
* See http://quilljs.com/docs/formats/
*/
Editor . formats = [
'header' ,
'font' ,
'size' ,
'bold' ,
'italic' ,
'underline' ,
'strike' ,
'blockquote' ,
'list' ,
'bullet' ,
'indent' ,
'link' ,
'image' ,
'color' ,
] ;
/*
* PropType validation
*/
Editor . propTypes = {
placeholder : React . PropTypes . string ,
} ;
/*
* Render component on page
*/
ReactDOM . render (
< Editor placeholder = { 'Write something or insert a star ★' } / > ,
document . querySelector ( '.app' )
) ;
El componente tiene dos tipos de formatos:
formats
. Todos los formatos están habilitados de forma predeterminada. import ReactQuill , { Quill } from 'react-quill' ; // ES6
const ReactQuill = require ( 'react-quill' ) ; // CommonJS
/*
* Example Parchment format from
* https://quilljs.com/guides/cloning-medium-with-parchment/
* See the video example in the guide for a complex format
*/
let Inline = Quill . import ( 'blots/inline' ) ;
class BoldBlot extends Inline { }
BoldBlot . blotName = 'bold' ;
BoldBlot . tagName = 'strong' ;
Quill . register ( 'formats/bold' , BoldBlot ) ;
const formats = [ 'bold' ] ; // add custom format name + any built-in formats you need
/*
* Editor component with default and custom formats
*/
class MyComponent extends React . Component {
constructor ( props ) {
this . formats = formats ;
this . state = { text : '' } ;
}
handleChange ( value ) {
this . setState ( { text : value } ) ;
}
render ( ) {
return (
< ReactQuill
value = { this . state . text }
onChange = { this . handleChange }
formats = { this . formats }
/ >
) ;
}
}
Si crea una instancia de ReactQuill sin hijos, creará un <div>
para usted, que se utilizará como área de edición para Quill. Si lo prefiere, puede especificar su propio elemento para que lo utilice ReactQuill. Tenga en cuenta que Quill no admite <textarea>
en este momento.
Nota: Las áreas de edición personalizadas pierden foco cuando se usa React 16 como departamento de pares en este momento (error).
class MyComponent extends React . Component {
render ( ) {
return (
< ReactQuill >
< div className = "my-editing-area" / >
< / ReactQuill >
) ;
}
} ) ;
Actualizar a ReactQuill v2 debería ser tan simple como actualizar su dependencia. Sin embargo, también elimina la compatibilidad con accesorios obsoletos durante mucho tiempo, ReactQuill Mixin y el componente Toolbar.
La compatibilidad con la toolbar
, styles
y las opciones pollInterval
Quill está deshabilitada desde hace mucho tiempo. A partir de esta versión, ReactQuill ya no le avisará si intenta usarlos.
ReactQuill Mixin permitió inyectar la funcionalidad principal que hizo que ReactQuill funcionara en sus propios componentes y crear versiones profundamente personalizadas.
El Mixin ha sido considerado un antipatrón desde hace mucho tiempo, por lo que hemos decidido finalizar su desaprobación.
No existe una ruta de actualización. Si tiene un caso de uso que dependía de Mixin, le recomendamos que abra un problema e intentaremos brindarle una nueva función para hacerlo posible, o soporte dedicado para migrar fuera de él.
Quill ha proporcionado durante mucho tiempo soporte integrado para barras de herramientas personalizadas, que reemplazaron el componente de barra de herramientas (bastante inflexible) de ReactQuill.
Utilice el módulo de barra de herramientas o la función de barra de herramientas HTML en su lugar.
// ES6
import ReactQuill , { Quill } from 'react-quill' ;
// CommonJS
const ReactQuill = require ( 'react-quill' ) ;
const { Quill } = ReactQuill ;
Quill
: el espacio de nombres Quill
al que puedes llamar para register
.
id
: ID que se aplicará al elemento DOM.
className
: clases que se aplicarán al elemento DOM.
value
: Valor para el editor como componente controlado. Puede ser una cadena que contenga HTML, una instancia de Quill Delta o un objeto simple que represente un Delta. Tenga en cuenta que debido a las limitaciones de Quill, este es en realidad un modo semicontrolado , lo que significa que no se impide la edición, pero cambiar value
seguirá reemplazando el contenido. También tenga en cuenta que pasar aquí un Quill Delta y luego una cadena HTML, o viceversa, siempre activará un cambio, independientemente de si representan el mismo documento.delta
del evento onChange
como value
, ya que provocará un bucle. Consulte Uso de deltas para obtener más detalles.
defaultValue
: valor inicial para el editor como componente no controlado. Puede ser una cadena que contenga HTML, un Quill Delta o un objeto simple que represente un Delta.
readOnly
: si es verdadero, el editor no permitirá cambiar su contenido. Envuelve la API disable
Quill.
placeholder
: el valor predeterminado para el editor vacío. Nota: La API de Quill no admite el cambio dinámico de este valor. Utilice referencias y atributos de datos en su lugar (consulte el n.º 340).
modules
: un objeto que especifica qué módulos están habilitados y su configuración. La barra de herramientas del editor es un módulo comúnmente personalizado. Consulte la sección de módulos en la documentación de Quill para obtener más información sobre los módulos disponibles.
formats
: una variedad de formatos que se habilitarán durante la edición. Todos los formatos implementados están habilitados de forma predeterminada. Consulte Formatos para obtener una lista. Los formatos personalizados no deben incluirse en la matriz a partir de la versión 1.0.0. En su lugar, deben crearse a través de Parchment y registrarse con la exportación Quill del módulo.
style
: un objeto con reglas CSS personalizadas para aplicar en el contenedor del editor. Las reglas deben tener el estilo de nomenclatura "camelCased" de React.
theme
: El nombre del tema que se aplicará al editor. El valor predeterminado es snow
, el tema estándar de Quill. Pase null
para utilizar el tema central mínimo. Consulte los documentos sobre temas para obtener más información sobre cómo incluir las hojas de estilo requeridas.
tabIndex
: el orden en el que el editor se enfoca, entre otros controles en la página, durante la navegación con el teclado.
bounds
: Selector o elemento DOM utilizado por Quill para restringir la posición de las ventanas emergentes. El valor predeterminado es document.body
.
children
: un único elemento de React que se utilizará como área de edición para Quill en lugar del valor predeterminado, que es un <div>
. Tenga en cuenta que no puede utilizar un <textarea>
, ya que no es un destino compatible. También tenga en cuenta que actualizar los elementos secundarios es costoso, ya que hará que se vuelva a crear el editor Quill. Establezca la propuesta value
si desea controlar el contenido html del editor.
onChange(content, delta, source, editor)
: se vuelve a llamar con el nuevo contenido del editor después del cambio. Se pasará el contenido HTML del editor, un objeto delta que expresa el cambio, la fuente del cambio y, finalmente, un proxy de solo lectura para los descriptores de acceso del editor como getHTML()
.delta
como value
, ya que provocará un bucle. Utilice editor.getContents()
en su lugar. Consulte Uso de deltas para obtener más detalles.
onChangeSelection(range, source, editor)
: se vuelve a llamar con el nuevo rango seleccionado, o es nulo cuando no está enfocado. Se pasará el rango de selección, la fuente del cambio y, finalmente, un proxy de solo lectura para los descriptores de acceso del editor, como getBounds()
.
onFocus(range, source, editor)
: se llama cuando el editor se enfoca. Recibirá el nuevo rango de selección.
onBlur(previousRange, source, editor)
: se llama cuando el editor pierde el foco. Recibirá el rango de selección que tenía justo antes de perder el foco.
onKeyPress(event)
: se llama después de presionar y soltar una tecla. : Tenga en cuenta que, al igual que su contraparte nativa, esto no se llamará para teclas especiales como Mayús o Intro . Si los necesita, conéctese a onKeyDown
o onKeyUp
.
onKeyDown(event)
: se llama después de presionar una tecla, pero antes de soltarla. : Tenga en cuenta que, debido al funcionamiento de Quill, es posible que no reciba eventos para teclas como Intro , Retroceso o Eliminar . Si ese es el caso, intente conectarse a onKeyUp
.
onKeyUp(event)
: se llama después de que se haya liberado una clave.
preserveWhitespace
: si es verdadero, se utiliza una etiqueta pre
para el área del editor en lugar de la etiqueta div
predeterminada. Esto evita que Quill colapse espacios en blanco continuos al pegar. Problema relacionado.
Si tiene una referencia a un nodo ReactQuill, podrá invocar los siguientes métodos:
focus()
: Enfoca el editor.
blur()
: Elimina el foco del editor.
getEditor()
: Devuelve la instancia de Quill que respalda al editor. Si bien puede usar esto libremente para acceder a métodos como getText()
, evite manipular imperativamente la instancia para evitar que ReactQuill y Quill no estén sincronizados. Un editor sin privilegios mucho más seguro está disponible como reemplazo.
Ver este ejemplo en Codepen
class Editor extends React . Component {
constructor ( props ) {
super ( props ) ;
this . quillRef = null ; // Quill instance
this . reactQuillRef = null ; // ReactQuill component
}
componentDidMount ( ) {
this . attachQuillRefs ( ) ;
}
componentDidUpdate ( ) {
this . attachQuillRefs ( ) ;
}
attachQuillRefs = ( ) => {
if ( typeof this . reactQuillRef . getEditor !== 'function' ) return ;
this . quillRef = this . reactQuillRef . getEditor ( ) ;
} ;
insertText = ( ) => {
var range = this . quillRef . getSelection ( ) ;
let position = range ? range . index : 0 ;
this . quillRef . insertText ( position , 'Hello, World! ' ) ;
} ;
render ( ) {
return (
< div >
< ReactQuill
ref = { ( el ) => {
this . reactQuillRef = el ;
} }
theme = { 'snow' }
/ >
< button onClick = { this . insertText } > Insert Text < / button >
< / div >
) ;
}
}
makeUnprivilegedEditor
: crea un editor sin privilegios. Pase a este método una referencia a la instancia de Quill desde getEditor
. Normalmente no es necesario utilizar este método ya que el editor expuesto a los controladores de eventos ya no tiene privilegios.
const editor = this . reactQuillRef . getEditor ( ) ;
const unprivilegedEditor = this . reactQuillRef . makeUnprivilegedEditor ( editor ) ;
// You may now use the unprivilegedEditor proxy methods
unprivilegedEditor . getText ( ) ;
Durante los eventos, ReactQuill pondrá a disposición un subconjunto restringido de la API de Quill como argumento editor
. Esto evita el acceso a métodos destructivos, lo que podría hacer que ReactQuill no esté sincronizado con el componente. Proporciona los siguientes métodos, que en su mayoría son sustitutos de los métodos Quill existentes:
getLength()
: Devuelve la longitud del contenido del editor, en caracteres, no inc.