Um componente Quill para React.
Veja uma demonstração ao vivo ou Codepen.
Esta é a documentação do ReactQuill v2 — Versões anteriores: v1
? ReactQuill v2
ReactQuill 2 está aqui, querido! E traz uma porta completa para TypeScript e React 16+, um sistema de construção refatorado e um reforço geral da lógica interna.
Trabalhamos muito para evitar a introdução de quaisquer mudanças comportamentais. Na grande maioria dos casos, nenhuma migração é necessária. No entanto, o suporte para adereços obsoletos, o ReactQuill Mixin e o componente Toolbar foram removidos. Não deixe de ler o guia de migração.
Esperamos que esta versão seja uma atualização imediata – se esse não for o caso, registre um problema com o rótulo v2
.
Certifique-se de ter react
e react-dom
e alguma forma de carregar estilos, como style-loader. Consulte a documentação sobre temas para obter mais informações.
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 >
No modo controlado, os componentes devem impedir alterações de estado locais e, em vez disso, apenas fazê-las acontecer por meio de onChange
e value
.
Como o Quill lida com suas próprias alterações e não permite a prevenção de edições, o ReactQuill precisa se contentar com um híbrido entre o modo controlado e o não controlado. Ele não pode impedir a alteração, mas ainda substituirá o conteúdo sempre que value
for diferente do estado atual.
Se você precisa frequentemente manipular o DOM ou usar as APIs do Quill de forma imperativa, você pode considerar mudar para o modo totalmente não controlado. ReactQuill inicializará o editor usando defaultValue
, mas não tentará redefini-lo depois disso. O retorno de chamada onChange
ainda funcionará conforme o esperado.
Leia mais sobre componentes não controlados na documentação do React.
Você pode passar um Quill Delta, em vez de uma string HTML, como as propriedades value
e defaultValue
. Deltas têm uma série de vantagens sobre strings HTML, então você pode querer usá-los. Esteja ciente, no entanto, que comparar Deltas para alterações é mais caro do que comparar strings HTML, portanto, pode valer a pena traçar o perfil de seus padrões de uso.
Observe que mudar value
de uma string HTML para um Delta, ou vice-versa, irá desencadear uma mudança, independentemente de representarem o mesmo documento, então você pode querer manter um formato e continuar usando-o de forma consistente.
delta
recebido do evento onChange
como value
. Este objeto não contém o documento completo, mas apenas as últimas modificações, e isso provavelmente acionará um loop infinito onde as mesmas alterações serão aplicadas continuamente. Use editor.getContents()
durante o evento para obter um Delta do documento completo. O ReactQuill impedirá que você cometa esse erro; no entanto, se você tiver certeza absoluta de que é isso que deseja, poderá passar o objeto por new Delta()
novamente para limpá-lo.
O editor Quill oferece suporte a temas. Inclui um tema completo, chamado neve , que é a aparência padrão de Quill, e um tema de bolha semelhante ao editor embutido do Medium. No mínimo, o tema principal deve ser incluído para que módulos como barras de ferramentas ou dicas de ferramentas funcionem.
Para ativar um tema, passe o nome do tema para o adereço theme
. Passe um valor falso (por exemplo, null
) para usar o tema principal.
< ReactQuill theme = "snow" . . . / >
Em seguida, importe a folha de estilo dos temas que deseja usar.
Isso pode variar dependendo de como o aplicativo está estruturado, diretórios ou outros. Por exemplo, se você usa um pré-processador CSS como SASS, você pode querer importar essa folha de estilo dentro do seu próprio. Essas folhas de estilo podem ser encontradas na distribuição do Quill, mas por conveniência elas também estão vinculadas na pasta dist
do ReactQuill.
Aqui está um exemplo usando style-loader para Webpack, ou create-react-app
, que injetará automaticamente os estilos na página:
import 'react-quill/dist/quill.snow.css' ;
Os estilos também estão disponíveis via CDN:
< link
rel =" stylesheet "
href =" https://unpkg.com/[email protected]/dist/quill.snow.css "
/>
A API Quill Toolbar Module fornece uma maneira fácil de configurar os ícones padrão da barra de ferramentas usando uma variedade de nomes 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 ;
Você também pode fornecer sua própria barra de ferramentas HTML/JSX com elementos personalizados que não fazem parte do tema Quill.
Veja este exemplo ao vivo no Codepen: Exemplo de barra de ferramentas 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' )
) ;
O componente possui dois tipos de formatos:
formats
. Todos os formatos estão habilitados por padrão. 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 }
/ >
) ;
}
}
Se você instanciar o ReactQuill sem filhos, ele criará um <div>
para você, para ser usado como área de edição do Quill. Se preferir, você pode especificar seu próprio elemento para o ReactQuill usar. Observe que <textarea>
s não são suportados pelo Quill no momento.
Nota: As áreas de edição personalizadas perdem o foco ao usar o React 16 como peer dep neste momento (bug).
class MyComponent extends React . Component {
render ( ) {
return (
< ReactQuill >
< div className = "my-editing-area" / >
< / ReactQuill >
) ;
}
} ) ;
Atualizar para ReactQuill v2 deve ser tão simples quanto atualizar sua dependência. No entanto, ele também remove o suporte para adereços obsoletos, o ReactQuill Mixin e o componente Toolbar.
O suporte para as opções de toolbar
, styles
e pollInterval
Quill está desativado há muito tempo. A partir desta versão, o ReactQuill não irá mais avisá-lo se você tentar usá-los.
O ReactQuill Mixin permitiu injetar a funcionalidade central que fez o ReactQuill funcionar em seus próprios componentes e criar versões profundamente personalizadas.
O Mixin já é considerado um antipadrão há muito tempo, então decidimos finalizar sua descontinuação.
Não há caminho de atualização. Se você tiver um caso de uso que dependa do Mixin, recomendamos que você abra um problema e tentaremos fornecer um novo recurso para tornar isso possível ou suporte dedicado para migrar dele.
O Quill há muito fornece suporte integrado para barras de ferramentas personalizadas, que substituíram o componente Toolbar (bastante inflexível) do ReactQuill.
Use o módulo da barra de ferramentas ou o recurso da barra de ferramentas HTML.
// ES6
import ReactQuill , { Quill } from 'react-quill' ;
// CommonJS
const ReactQuill = require ( 'react-quill' ) ;
const { Quill } = ReactQuill ;
Quill
: O namespace Quill
no qual você pode chamar register
.
id
: ID a ser aplicado ao elemento DOM.
className
: Classes a serem aplicadas ao elemento DOM.
value
: Valor para o editor como um componente controlado. Pode ser uma string contendo HTML, uma instância Quill Delta ou um objeto simples representando um Delta. Observe que devido às limitações do Quill, este é na verdade um modo semicontrolado , o que significa que a edição não é impedida, mas a alteração value
ainda substituirá o conteúdo. Observe também que passar um Quill Delta aqui e depois uma string HTML, ou vice-versa, sempre acionará uma alteração, independentemente de representarem o mesmo documento.delta
do evento onChange
como value
, pois isso causará um loop. Consulte Usando Deltas para obter detalhes.
defaultValue
: Valor inicial do editor como um componente não controlado. Pode ser uma string contendo HTML, um Quill Delta ou um objeto simples representando um Delta.
readOnly
: Se for verdade, o editor não permitirá alterar seu conteúdo. Envolve a API disable
do Quill.
placeholder
: o valor padrão para o editor vazio. Observação: a API Quill não oferece suporte à alteração desse valor dinamicamente. Em vez disso, use refs e data-attributes (veja #340).
modules
: um objeto que especifica quais módulos estão habilitados e sua configuração. A barra de ferramentas do editor é um módulo comumente personalizado. Consulte a seção de módulos na documentação do Quill para obter mais informações sobre quais módulos estão disponíveis.
formats
: uma variedade de formatos a serem ativados durante a edição. Todos os formatos implementados estão habilitados por padrão. Consulte Formatos para obter uma lista. Os formatos personalizados não devem ser incluídos no array a partir da versão 1.0.0. Em vez disso, eles devem ser criados através do Parchment e registrados na exportação Quill do módulo.
style
: um objeto com regras CSS personalizadas para aplicar no contêiner do editor. As regras devem estar no estilo de nomenclatura "camelCased" do React.
theme
: O nome do tema a ser aplicado ao editor. O padrão é snow
, o tema padrão de Quill. Passe null
para usar o tema central mínimo. Consulte a documentação sobre temas para obter mais informações sobre como incluir as folhas de estilo necessárias.
tabIndex
: A ordem em que o editor fica em foco, entre outros controles na página, durante a navegação pelo teclado.
bounds
: seletor ou elemento DOM usado por Quill para restringir a posição dos pop-ups. O padrão é document.body
.
children
: Um único elemento React que será usado como área de edição para Quill no lugar do padrão, que é um <div>
. Observe que você não pode usar <textarea>
, pois não é um destino compatível. Observe também que atualizar os filhos é caro, pois fará com que o editor Quill seja recriado. Defina a proposta value
se quiser controlar o conteúdo HTML do editor.
onChange(content, delta, source, editor)
: Chamado de volta com o novo conteúdo do editor após a alteração. Será passado o conteúdo HTML do editor, um objeto delta expressando a mudança, a fonte da mudança e, finalmente, um proxy somente leitura para acessadores do editor, como getHTML()
.delta
como value
, pois isso causará um loop. Use editor.getContents()
em vez disso. Consulte Usando Deltas para obter detalhes.
onChangeSelection(range, source, editor)
: Chamado de volta com o novo intervalo selecionado ou nulo quando fora de foco. Será passado o intervalo de seleção, a origem da alteração e, finalmente, um proxy somente leitura para acessadores de editor como getBounds()
.
onFocus(range, source, editor)
: Chamado quando o editor fica em foco. Ele receberá o novo intervalo de seleção.
onBlur(previousRange, source, editor)
: Chamado quando o editor perde o foco. Ele receberá a faixa de seleção que tinha antes de perder o foco.
onKeyPress(event)
: Chamado após uma tecla ser pressionada e liberada. : Observe que, como sua contraparte nativa, não será chamado para teclas especiais como shift ou enter . Se você precisar deles, conecte-se onKeyDown
ou onKeyUp
.
onKeyDown(event)
: Chamado após uma tecla ser pressionada, mas antes de ser liberada. : Observe que, devido ao funcionamento do Quill, é possível que você não receba eventos para teclas como enter , backspace ou delete . Se for esse o caso, tente conectar-se ao onKeyUp
.
onKeyUp(event)
: Chamado após uma chave ser liberada.
preserveWhitespace
: se verdadeiro, uma tag pre
será usada para a área do editor em vez da tag div
padrão. Isso evita que o Quill recolha espaços em branco contínuos na colagem. Questão relacionada.
Se você tiver uma referência para um nó ReactQuill, poderá invocar os seguintes métodos:
focus()
: foca o editor.
blur()
: Remove o foco do editor.
getEditor()
: Retorna a instância Quill que suporta o editor. Embora você possa usar isso livremente para acessar métodos como getText()
, evite manipular imperativamente a instância, para evitar que ReactQuill e Quill fiquem fora de sincronia. Um editor sem privilégios muito mais seguro está disponível como substituto.
Veja este exemplo no 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
: Cria um editor sem privilégios. Passe para este método uma referência à instância Quill de getEditor
. Normalmente você não precisa usar este método, pois o editor exposto aos manipuladores de eventos já não tem privilégios.
const editor = this . reactQuillRef . getEditor ( ) ;
const unprivilegedEditor = this . reactQuillRef . makeUnprivilegedEditor ( editor ) ;
// You may now use the unprivilegedEditor proxy methods
unprivilegedEditor . getText ( ) ;
Durante os eventos, o ReactQuill disponibilizará um subconjunto restrito da API Quill como argumento editor
. Isso evita o acesso a métodos destrutivos, o que pode fazer com que o ReactQuill fique fora de sincronia com o componente. Ele fornece os seguintes métodos, que são principalmente proxies de métodos Quill existentes:
getLength()
: Retorna o comprimento do conteúdo do editor, em caracteres, não inc