Un composant Quill pour React.
Voir une démo en direct ou Codepen.
Ceci est la documentation de ReactQuill v2 — Versions précédentes : v1
? ReactQuillv2
ReactQuill 2 est là, bébé ! Et il apporte un portage complet vers TypeScript et React 16+, un système de build refactorisé et un resserrement général de la logique interne.
Nous avons travaillé dur pour éviter d’introduire des changements de comportement. Dans la grande majorité des cas, aucune migration n’est nécessaire. Cependant, la prise en charge des accessoires obsolètes depuis longtemps, du ReactQuill Mixin et du composant Toolbar a été supprimée. Assurez-vous de lire le guide de migration.
Nous nous attendons à ce que cette version soit une mise à niveau immédiate – si ce n'est pas le cas, veuillez signaler un problème avec l'étiquette v2
.
Assurez-vous d'avoir react
et react-dom
, ainsi qu'un moyen de charger les styles, comme style-loader. Voir la documentation sur les thèmes pour plus d'informations.
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 mode contrôlé, les composants sont censés empêcher les changements d'état locaux et les faire se produire uniquement via onChange
et value
.
Étant donné que Quill gère ses propres modifications et ne permet pas d'empêcher les modifications, ReactQuill doit se contenter d'un hybride entre le mode contrôlé et non contrôlé. Il ne peut pas empêcher le changement, mais remplacera toujours le contenu chaque fois que value
diffère de l'état actuel.
Si vous avez fréquemment besoin de manipuler le DOM ou d'utiliser impérativement les API Quill, vous pouvez envisager de passer en mode totalement non contrôlé. ReactQuill initialisera l'éditeur en utilisant defaultValue
, mais n'essaiera pas de le réinitialiser par la suite. Le rappel onChange
fonctionnera toujours comme prévu.
En savoir plus sur les composants non contrôlés dans la documentation React.
Vous pouvez transmettre un Quill Delta, au lieu d’une chaîne HTML, comme propriétés value
et defaultValue
. Les deltas présentent un certain nombre d'avantages par rapport aux chaînes HTML, vous souhaiterez donc peut-être les utiliser à la place. Sachez cependant que comparer les Deltas pour les modifications coûte plus cher que comparer les chaînes HTML, il peut donc être utile de profiler vos modèles d'utilisation.
Notez que le passage d'une value
d'une chaîne HTML à un Delta, ou vice versa, déclenchera un changement, qu'il s'agisse ou non du même document, vous souhaiterez donc peut-être vous en tenir à un format et continuer à l'utiliser de manière cohérente tout au long.
delta
que vous recevez de l'événement onChange
comme value
. Cet objet ne contient pas le document complet, mais uniquement les dernières modifications, ce qui déclenchera très probablement une boucle infinie où les mêmes modifications seront appliquées encore et encore. Utilisez editor.getContents()
pendant l'événement pour obtenir un Delta du document complet à la place. ReactQuill vous empêchera de commettre une telle erreur, mais si vous êtes absolument sûr que c'est ce que vous voulez, vous pouvez à nouveau passer l'objet via new Delta()
pour le corriger.
L'éditeur Quill prend en charge les thèmes. Il comprend un thème à part entière, appelé snow , qui est l'apparence standard de Quill, et un thème de bulle similaire à l'éditeur en ligne de Medium. À tout le moins, le thème principal doit être inclus pour que des modules tels que les barres d'outils ou les info-bulles fonctionnent.
Pour activer un thème, transmettez le nom du thème à l'accessoire theme
. Passez une valeur fausse (par exemple null
) pour utiliser le thème principal.
< ReactQuill theme = "snow" . . . / >
Ensuite, importez la feuille de style pour les thèmes que vous souhaitez utiliser.
Cela peut varier en fonction de la façon dont l'application est structurée, des répertoires ou autre. Par exemple, si vous utilisez un préprocesseur CSS tel que SASS, vous souhaiterez peut-être importer cette feuille de style dans la vôtre. Ces feuilles de style peuvent être trouvées dans la distribution Quill, mais pour plus de commodité, elles sont également liées dans le dossier dist
de ReactQuill.
Voici un exemple utilisant style-loader pour Webpack, ou create-react-app
, qui injectera automatiquement les styles sur la page :
import 'react-quill/dist/quill.snow.css' ;
Les styles sont également disponibles via CDN :
< link
rel =" stylesheet "
href =" https://unpkg.com/[email protected]/dist/quill.snow.css "
/>
L'API du module Quill Toolbar fournit un moyen simple de configurer les icônes de la barre d'outils par défaut à l'aide d'un tableau de noms de format.
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 ;
Vous pouvez également fournir votre propre barre d'outils HTML/JSX avec des éléments personnalisés qui ne font pas partie du thème Quill.
Voir cet exemple en direct sur Codepen : Exemple de barre d'outils personnalisée
/*
* 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' )
) ;
Le composant a deux types de formats :
formats
. Tous les formats sont activés par défaut. 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 vous instanciez ReactQuill sans enfants, il créera un <div>
pour vous, à utiliser comme zone d'édition pour Quill. Si vous préférez, vous pouvez spécifier votre propre élément que ReactQuill devra utiliser. Notez que les <textarea>
ne sont pas pris en charge par Quill pour le moment.
Remarque : les zones d'édition personnalisées perdent le focus lors de l'utilisation de React 16 en tant que développeur homologue pour le moment (bug).
class MyComponent extends React . Component {
render ( ) {
return (
< ReactQuill >
< div className = "my-editing-area" / >
< / ReactQuill >
) ;
}
} ) ;
La mise à niveau vers ReactQuill v2 devrait être aussi simple que de mettre à jour votre dépendance. Cependant, il supprime également la prise en charge des accessoires obsolètes depuis longtemps, du ReactQuill Mixin et du composant Toolbar.
La prise en charge de la toolbar
, styles
et des options pollInterval
Quill est désactivée depuis longtemps. À partir de cette version, ReactQuill ne vous avertira plus si vous essayez de les utiliser.
Le ReactQuill Mixin a permis d'injecter la fonctionnalité de base qui a permis à ReactQuill de fonctionner dans vos propres composants et de créer des versions profondément personnalisées.
Le Mixin est considéré depuis longtemps comme un anti-pattern, nous avons donc décidé de finaliser sa dépréciation.
Il n'y a pas de chemin de mise à niveau. Si vous avez un cas d'utilisation qui repose sur Mixin, nous vous encourageons à ouvrir un ticket et nous essaierons de vous fournir une nouvelle fonctionnalité pour le rendre possible, ou un support dédié pour en sortir.
Quill fournit depuis longtemps un support intégré pour les barres d'outils personnalisées, qui ont remplacé le composant Toolbar (assez rigide) de ReactQuill.
Utilisez plutôt le module de barre d'outils ou la fonctionnalité de barre d'outils HTML.
// ES6
import ReactQuill , { Quill } from 'react-quill' ;
// CommonJS
const ReactQuill = require ( 'react-quill' ) ;
const { Quill } = ReactQuill ;
Quill
: L'espace de noms Quill
sur lequel vous pouvez appeler register
.
id
: ID à appliquer à l'élément DOM.
className
: Classes à appliquer à l'élément DOM.
value
: Valeur pour l'éditeur en tant que composant contrôlé. Peut être une chaîne contenant du HTML, une instance Quill Delta ou un objet simple représentant un Delta. Notez qu'en raison des limitations de Quill, il s'agit en fait d'un mode semi-contrôlé , ce qui signifie que la modification n'est pas empêchée, mais que la modification value
remplacera toujours le contenu. Notez également que passer un Quill Delta ici, puis une chaîne HTML, ou vice versa, déclenchera toujours une modification, qu'ils représentent ou non le même document.delta
de l'événement onChange
en tant que value
, car cela provoquerait une boucle. Voir Utilisation des deltas pour plus de détails.
defaultValue
: Valeur initiale de l'éditeur en tant que composant non contrôlé. Peut être une chaîne contenant du HTML, un Quill Delta ou un objet simple représentant un Delta.
readOnly
: Si vrai, l'éditeur n'autorisera pas à modifier son contenu. Encapsule l'API disable
de Quill.
placeholder
: La valeur par défaut pour l’éditeur vide. Remarque : L'API Quill ne prend pas en charge la modification dynamique de cette valeur. Utilisez plutôt les références et les attributs de données (voir #340).
modules
: Un objet spécifiant quels modules sont activés et leur configuration. La barre d'outils de l'éditeur est un module couramment personnalisé. Consultez la section modules de la documentation Quill pour plus d'informations sur les modules disponibles.
formats
: Un tableau de formats à activer lors de l’édition. Tous les formats implémentés sont activés par défaut. Voir Formats pour une liste. Les formats personnalisés ne doivent pas être inclus dans le tableau à partir de la version 1.0.0. Au lieu de cela, ils doivent être créés via Parchment et enregistrés avec l'exportation Quill du module.
style
: Un objet avec des règles CSS personnalisées à appliquer sur le conteneur de l'éditeur. Les règles doivent être dans le style de dénomination « camelCased » de React.
theme
: Le nom du thème à appliquer à l'éditeur. La valeur par défaut est snow
, le thème standard de Quill. Passez null
pour utiliser le thème principal minimal. Consultez la documentation sur les thèmes pour plus d'informations sur l'inclusion des feuilles de style requises.
tabIndex
: L'ordre dans lequel l'éditeur devient actif, entre autres contrôles de la page, lors de la navigation au clavier.
bounds
: Sélecteur ou élément DOM utilisé par Quill pour contraindre la position des popups. La valeur par défaut est document.body
.
children
: Un seul élément React qui sera utilisé comme zone d'édition pour Quill à la place de la valeur par défaut, qui est un <div>
. Notez que vous ne pouvez pas utiliser un <textarea>
, car ce n'est pas une cible prise en charge. Notez également que la mise à jour des enfants est coûteuse, car elle entraînera la recréation de l'éditeur Quill. Définissez la value
prop si vous souhaitez contrôler le contenu HTML de l'éditeur.
onChange(content, delta, source, editor)
: Rappelé avec le nouveau contenu de l'éditeur après modification. Il sera transmis au contenu HTML de l'éditeur, à un objet delta exprimant le changement, à la source du changement et enfin à un proxy en lecture seule pour les accesseurs de l'éditeur tels que getHTML()
.delta
comme value
, car cela provoquerait une boucle. Utilisez plutôt editor.getContents()
. Voir Utilisation des deltas pour plus de détails.
onChangeSelection(range, source, editor)
: Rappelé avec la nouvelle plage sélectionnée, ou null lorsqu'il n'est pas focalisé. La plage de sélection, la source du changement et enfin un proxy en lecture seule pour les accesseurs de l'éditeur tels que getBounds()
lui seront transmis.
onFocus(range, source, editor)
: Appelé lorsque l'éditeur devient focus. Il recevra la nouvelle plage de sélection.
onBlur(previousRange, source, editor)
: Appelé lorsque l'éditeur perd le focus. Il recevra la plage de sélection dont il disposait juste avant de perdre le focus.
onKeyPress(event)
: Appelé après qu'une touche a été enfoncée et relâchée. : Notez que, comme son homologue natif, cela ne sera pas appelé pour des touches spéciales telles que shift ou enter . Si vous en avez besoin, connectez-vous à onKeyDown
ou onKeyUp
.
onKeyDown(event)
: Appelé après qu'une touche a été enfoncée, mais avant qu'elle ne soit relâchée. : Notez qu'en raison du fonctionnement de Quill, il est possible que vous ne receviez pas d'événements pour des touches telles que enter , backspace ou delete . Si tel est le cas, essayez plutôt de vous connecter à onKeyUp
.
onKeyUp(event)
: Appelé après qu'une clé ait été relâchée.
preserveWhitespace
: Si vrai, une balise pre
est utilisée pour la zone de l'éditeur au lieu de la balise div
par défaut. Cela empêche Quill de réduire les espaces continus lors du collage. Problème connexe.
Si vous avez une référence à un nœud ReactQuill, vous pourrez invoquer les méthodes suivantes :
focus()
: Focuse l'éditeur.
blur()
: Supprime le focus de l'éditeur.
getEditor()
: renvoie l'instance Quill qui soutient l'éditeur. Bien que vous puissiez l'utiliser librement pour accéder à des méthodes telles que getText()
, évitez de manipuler impérativement l'instance, pour éviter de désynchroniser ReactQuill et Quill. Un éditeur non privilégié beaucoup plus sûr est disponible en remplacement.
Voir cet exemple sur 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
: Crée un éditeur non privilégié. Transmettez à cette méthode une référence à l’instance Quill depuis getEditor
. Normalement, vous n'avez pas besoin d'utiliser cette méthode puisque l'éditeur exposé aux gestionnaires d'événements n'est déjà pas privilégié.
const editor = this . reactQuillRef . getEditor ( ) ;
const unprivilegedEditor = this . reactQuillRef . makeUnprivilegedEditor ( editor ) ;
// You may now use the unprivilegedEditor proxy methods
unprivilegedEditor . getText ( ) ;
Lors d'événements, ReactQuill rendra disponible un sous-ensemble restreint de l'API Quill comme argument editor
. Cela empêche l'accès aux méthodes destructrices, ce qui pourrait entraîner une désynchronisation de ReactQuill avec le composant. Il fournit les méthodes suivantes, qui sont pour la plupart des proxys des méthodes Quill existantes :
getLength()
: Renvoie la longueur du contenu de l'éditeur, en caractères, pas en inc.