CSS Discussion Frontend HTML Javascript jQuery React.js Vue.js

Quill is a modern WYSIWYG editor built for compatibility and extensibility

Quickstart in jQuery

The best way to get started is try a simple example. Quill is initialized with a DOM element to contain the editor. The contents of that element will become the initial contents of Quill.

<!-- Include stylesheet -->
<link href="https://cdn.quilljs.com/1.3.6/quill.snow.css" rel="stylesheet">

<!-- Create the editor container -->
<div id="editor">
  <p>Hello World!</p>
  <p>Some initial <strong>bold</strong> text</p>
  <p><br></p>
</div>

<!-- Include the Quill library -->
<script src="https://cdn.quilljs.com/1.3.6/quill.js"></script>

<!-- Initialize Quill editor -->
<script>
  var quill = new Quill('#editor', {
    theme: 'snow'
  });
</script>

And that’s all there is to it!

Next Steps

The real magic of Quill comes in its flexibility and extensibility. You can get an idea of what is possible by playing around with the demos throughout this site or head straight to the Interactive Playground. For an in-depth walkthrough, take a look at How to Customize Quill.

React-Quill   

Quill component for React.

See a live demo or Codepen.

  1. Quick start
    1. Import the component
    2. Import the stylesheet
    3. Use the component
    4. Using Deltas
    5. Controlled vs Uncontrolled Mode
  2. Options
    1. Theme
    2. Custom Toolbar
    3. Custom Formats
    4. Custom Editing Area
    5. Mixin
  3. Upgrading to React-Quill v1.0.0
  4. API reference
    1. Exports
    2. Props
    3. Methods
  5. Browser support
  6. Building and testing
    1. Bundling with Webpack
  7. Changelog
  8. Contributors
  9. License

💯 React Quill now supports Quill v1.0.0! Thanks to @clemmy and @alexkrolick for landing this much-awaited change. There are many breaking changes, so be sure to read the migration guide.


npm install react-quillyarn add react-quill

Special thank you to everyone who contributed during the 1.0.0 release cycle!

Quick Start

Import the component

import ReactQuill from 'react-quill'; // ES6import * as ReactQuill from 'react-quill'; // Typescriptconst ReactQuill = require('react-quill'); // CommonJS

Import the stylesheet

Two common examples are shown below. How stylesheets are included in your app depends on build system (Webpack, SCSS, LESS, etc). See the documentation on Themes for more information.

Fetching styles from the CDN

<link rel="stylesheet" href="//cdn.quilljs.com/1.2.6/quill.snow.css">

Using css-loader with Webpack or create-react-app

require('react-quill/dist/quill.snow.css'); // CommonJSimport 'react-quill/dist/quill.snow.css'; // ES6

Use the component

class MyComponent extends React.Component {  constructor(props) {    super(props)    this.state = { text: '' } // You can also pass a Quill Delta here    this.handleChange = this.handleChange.bind(this)  }   handleChange(value) {    this.setState({ text: value })  }   render() {    return (      <ReactQuill value={this.state.text}                  onChange={this.handleChange} />    )  }}

Using Deltas

You can pass a Quill Delta, instead of an HTML string, as the value and defaultValueproperties. Deltas have a number of advantages over HTML strings, so you might want use them instead. Be aware, however, that comparing Deltas for changes is more expensive than comparing HTML strings, so it might be worth to profile your usage patterns.

Note that switching value from an HTML string to a Delta, or vice-versa, will trigger a change, regardless of whether they represent the same document, so you might want to stick to a format and keep using it consistently throughout.

⚠️ Do not use the delta object you receive from the onChange event as value. This object does not contain the full document, but only the last modifications, and doing so will most likely trigger an infinite loop where the same changes are applied over and over again. Use editor.getContents() during the event to obtain a Delta of the full document instead. ReactQuill will prevent you from making such a mistake, however if you are absolutely sure that this is what you want, you can pass the object through new Delta() again to un-taint it.

Controlled vs Uncontrolled Mode

Pass defaultValue instead of value if you need to use DOM or Quill APIs to imperatively manipulate the editor state. In this “uncontrolled” mode ReactQuill uses the prop as the initial value but allows the element to deviate after that. The onChange callback still works normally.

  • Read more about uncontrolled components in the React docs.
  • Read more about the available props.

Options

Theme

The Quill editor supports themes. It includes a full-fledged theme, called snow, that is Quill’s standard appearance, a bubble theme that is similar to the inline editor on Medium, and a coretheme containing only the bare essentials to allow modules like toolbars or tooltips to work.

These stylesheets can be found in the Quill distribution, but for convenience they are also linked in React Quill’s dist folder. In a common case you would activate a theme by setting the theme prop. Pass a falsy value (null) to disable the theme.

<ReactQuill theme="snow" /> // or "bubble", null to use minimal core theme

And then link the appropriate stylesheet (only link the CSS for the themes you want to use):

<link rel="stylesheet" href="node_modules/react-quill/dist/quill.snow.css"><link rel="stylesheet" href="node_modules/react-quill/dist/quill.bubble.css"><link rel="stylesheet" href="node_modules/react-quill/dist/quill.core.css">

This may vary depending how application is structured, directories or otherwise. For example, if you use a CSS pre-processor like SASS, you may want to import that stylesheet inside your own.

Custom Toolbar

Default Toolbar Elements

The Quill Toolbar Module API provides an easy way to configure the default toolbar icons using an array of format names.Example Code

HTML Toolbar

You can also supply your own HTML/JSX toolbar with custom elements that are not part of the Quill theme.

See this example live on Codepen: Custom Toolbar ExampleExample Code

Custom Formats

The component has two types of formats:

  1. The default Quill formats that are enabled/disabled using the formats prop. All formats are enabled by default.
  2. Custom formats created using Parchment and registered with your component’s Quill instance

Example Code

Custom editing area

If you instantiate ReactQuill without children, it will create a <div> for you, to be used as the editing area for Quill. If you prefer, you can specify your own element for ReactQuill to use. Note that <textarea>s are not supported by Quill at this time.

Note: Custom editing areas lose focus when using React 16 as a peer dep at this time (bug).

Mixin

The module exports a mixin which can be used to create custom editor components. (Note that mixins will be deprecated in a future version of React).Example Code

Upgrading to React-Quill v1.0.0

In most cases, ReactQuill will raise useful warnings to help you perform any necessary migration steps.

Please note that many migration steps to Quill v1.0 may also apply.Expand Upgrade Guide

API reference

Exports

const ReactQuill = require('react-quill'); // CommonJSconst {Quill, Mixin, Toolbar} = ReactQuill; import ReactQuill, { Quill, Mixin, Toolbar } from 'react-quill'; // ES6

Mixin : Provides the bridge between React and Quill. ReactQuill implements this mixin; in the same way you can use it to build your own component, or replace it to implement a new core for the default component. Note that mixins are deprecated in React and this export will be replaced by an HOC in the future.

Toolbar : The component that renders the custom ReactQuill toolbar. The default collection of items and color swatches is available as ReactQuill.Toolbar.defaultItems and ReactQuill.Toolbar.defaultColors respectively. ⚠️ The Toolbar component is deprecated since v1.0.0. See upgrading to React Quill v1.0.0.

Quill : The Quill namespace on which you can call registerModule and such.

Props

id : ID to be applied to the DOM element.

className : Classes to be applied to the DOM element.

value : Value for the editor as a controlled component. Can be a string containing HTML, a Quill Delta instance, or a plain object representing a Delta. Note that due to limitations in Quill, this is actually a semi-controlled mode, meaning that the edit is not prevented, but changing value will still replace the contents. Also note that passing a Quill Delta here, and then an HTML string, or vice-versa, will always trigger a change, regardless of whether they represent the same document. ⚠️ Do not pass the delta object from the onChange event as value, as it will cause a loop. See Using Deltas for details.

defaultValue : Initial value for the editor as an uncontrolled component. Can be a string containing HTML, a Quill Delta, or a plain object representing a Delta.

readOnly : If true, the editor won’t allow changing its contents. Wraps the Quill disable API.

placeholder : The default value for the empty editor. Note: The Quill API does not support changing this value dynamically. Use refs and data-attributes instead (see #340).

modules : An object specifying which modules are enabled, and their configuration. The editor toolbar is a commonly customized module. See the modules section over the Quill documentation for more information on what modules are available.

formats : An array of formats to be enabled during editing. All implemented formats are enabled by default. See Formats for a list. Custom formats should not be included in the array as of version 1.0.0. Instead they should be created through Parchment and registered with the module’s Quill export.

style : An object with custom CSS rules to apply on the editor’s container. Rules should be in React’s “camelCased” naming style.

theme : The name of the theme to apply to the editor. Defaults to snow, Quill’s standard theme. Pass null to use the minimal core theme. See the docs on themes for more information on including the required stylesheets.

tabIndex : The order in which the editor becomes focused, among other controls in the page, during keyboard navigation.

bounds : Selector or DOM element used by Quill to constrain position of popups. Defaults to document.body.

children : A single React element that will be used as the editing area for Quill in place of the default, which is a <div>. Note that you cannot use a <textarea>, as it is not a supported target. Also note that updating children is costly, as it will cause the Quill editor to be recreated. Set the value prop if you want to control the html contents of the editor.

onChange(content, delta, source, editor) : Called back with the new contents of the editor after change. It will be passed the HTML contents of the editor, a delta object expressing the change, the source of the change, and finally a read-only proxy to editor accessors such as getHTML(). ⚠️ Do not use this delta object as value, as it will cause a loop. Use editor.getContents() instead. See Using Deltas for details.

onChangeSelection(range, source, editor) : Called back with the new selected range, or null when unfocused. It will be passed the selection range, the source of the change, and finally a read-only proxy to editor accessors such as getBounds().

onFocus(range, source, editor) : Called when the editor becomes focused. It will receive the new selection range.

onBlur(previousRange, source, editor) : Called when the editor loses focus. It will receive the selection range it had right before losing focus.

onKeyPress(event) : Called after a key has been pressed and released. : Note that, like its native counterpart, this won’t be called for special keys such as shift or enter. If you need those, hook onto onKeyDown or onKeyUp.

onKeyDown(event) : Called after a key has been pressed, but before it is released. : Note that, due to how Quill works, it’s possible that you won’t receive events for keys such as enter, backspace or delete. If that’s the case, try hooking onto onKeyUp instead.

onKeyUp(event) : Called after a key has been released.

preserveWhitespace : If true, a pre tag is used for the editor area instead of the default div tag. This prevents Quill from collapsing continuous whitespaces on paste. Related issue.

Methods

If you have a ref to a ReactQuill node, you will be able to invoke the following methods:

focus() : Focuses the editor.

blur() : Removes focus from the editor.

getEditor() : Returns the Quill instance that backs the editor. While you can freely use this to access methods such as getText(), please avoid from imperatively manipulating the instance, to avoid getting ReactQuill and Quill out-of-sync. A much-safer unprivileged editor is available as replacement.Example

makeUnprivilegedEditor : Creates an unprivileged editor. Pass this method a reference to the Quill instance from getEditor. Normally you do not need to use this method since the editor exposed to event handlers is already unprivileged.Example

The unprivileged editor

During events, ReactQuill will make a restricted subset of the Quill API available as the editorargument. This prevents access to destructive methods, which might cause ReactQuill to get out-of-sync with the component. It provides the following methods, which are mostly proxies of existing Quill methods:

getLength() : Returns the length of the editor contents, in characters, not including any HTML tag.

getText() : Returns the string contents of the editor, not including any HTML tag.

getHTML() : Returns the full HTML contents of the editor.

getContents() : Returns a Quill Delta of the complete document.

getSelection() : Returns the current selection range, or null if the editor is unfocused.

getBounds() : Returns the pixel position, relative to the editor container, and dimensions, of a selection, at a given location.

Building and testing

You can run the automated test suite:

npm test

And build a minificated version of the source:

npm run build

More tasks are available on the Makefile:

lint: lints the source
spec: runs the test specs
coverage: runs the code coverage test
test: lint, spec and coverage threshold test
build: builds the minified version

Note that dist is ignored in the git repository as of version 1.0.0. If you need to use the built files without downloading the package from NPM, you can run the build tasks yourself or use a CDN like unpkg.

Bundling with Webpack

Quill ships only a pre-built javascript file, so Webpack will complain after building a bundle:

Error: ./~/react-quill/~/quill/dist/quill.js
Critical dependencies:
6:478-485 This seems to be a pre-built javascript file. Though this is possible, it's not recommended. Try to require the original source to get better results.
@ ./~/react-quill/~/quill/dist/quill.js 6:478-485

The warning is harmless, but if you want to silence it you can avoid parsing Quill by adding this to your Webpack configuration:

module: {  // Shut off warnings about using pre-built javascript files  // as Quill.js unfortunately ships one as its `main`.  noParse: /node_modules\/quill\/dist/}

Vue-Quill-Editor

🍡Quill editor component for Vue, support SPA and SSR.

基于 Quill、适用于 Vue 的富文本编辑器,支持服务端渲染和单页应用。

Example

Demo Page

CDN Example

Nuxt.js/SSR example code

Projects Using Vue-Quill-Editor

Tamiat CMS

Install

CDN

<link rel="stylesheet" href="path/to/quill.core.css"/><link rel="stylesheet" href="path/to/quill.snow.css"/><link rel="stylesheet" href="path/to/quill.bubble.css"/><script type="text/javascript" src="path/to/quill.js"></script><script type="text/javascript" src="path/to/vue.min.js"></script><script type="text/javascript" src="path/to/dist/vue-quill-editor.js"></script><script type="text/javascript">  Vue.use(window.VueQuillEditor)</script> 

NPM

npm install vue-quill-editor --save

Mount

mount with global

import Vue from 'vue'import VueQuillEditor from 'vue-quill-editor' // require stylesimport 'quill/dist/quill.core.css'import 'quill/dist/quill.snow.css'import 'quill/dist/quill.bubble.css' Vue.use(VueQuillEditor, /* { default global options } */)

mount with component

// require stylesimport 'quill/dist/quill.core.css'import 'quill/dist/quill.snow.css'import 'quill/dist/quill.bubble.css' import { quillEditor } from 'vue-quill-editor' export default {  components: {    quillEditor  }}

mount with ssr

// if used in nuxt.js/ssr, you should keep require it only in browser build environmentif (process.browser) {  const VueQuillEditor = require('vue-quill-editor/dist/ssr')  Vue.use(VueQuillEditor, /* { default global options } */)}

register quill module

// register quill modules, you need to introduce and register before the vue program is instantiatedimport Quill from 'quill'import yourQuillModule from '../yourModulePath/yourQuillModule.js'Quill.register('modules/yourQuillModule', yourQuillModule)

Difference(使用方法的区别)

SSR and the only difference in the use of the SPA:

  • SPA worked by the component, find quill instance by ref attribute.
  • SSR worked by the directive, find quill instance by directive arg.
  • Other configurations, events are the same.

SSR

<!-- You can custom the "myQuillEditor" name used to find the quill instance in current component --><template>  <!-- bidirectional data binding(双向数据绑定) -->  <div class="quill-editor"        v-model="content"       v-quill:myQuillEditor="editorOption">  </div>   <!-- Or manually control the data synchronization(手动控制数据流)  -->  <div class="quill-editor"        :content="content"       @change="onEditorChange($event)"       v-quill:myQuillEditor="editorOption">  </div></template> <script>  export default {    data() {      return {        content: '<p>example content</p>',        editorOption: { /* quill options */ }      }    },    mounted() {      console.log('this is current quill instance object', this.myQuillEditor)    },    methods: {      onEditorChange(event) {        console.log('onEditorChange')      }    },    // Omit the same parts as in the following component sample code    // ...  }</script>

SPA

<template>  <!-- bidirectional data binding(双向数据绑定) -->  <quill-editor v-model="content"                ref="myQuillEditor"                :options="editorOption"                @blur="onEditorBlur($event)"                @focus="onEditorFocus($event)"                @ready="onEditorReady($event)">  </quill-editor>   <!-- Or manually control the data synchronization(或手动控制数据流) -->  <quill-editor :content="content"                :options="editorOption"                @change="onEditorChange($event)">  </quill-editor></template> <script>   // you can also register quill modules in the component  import Quill from 'quill'  import { someModule } from '../yourModulePath/someQuillModule.js'  Quill.register('modules/someModule', someModule)    export default {    data () {      return {        content: '<h2>I am Example</h2>',        editorOption: {          // some quill options        }      }    },    // manually control the data synchronization    // 如果需要手动控制数据同步,父组件需要显式地处理changed事件    methods: {      onEditorBlur(quill) {        console.log('editor blur!', quill)      },      onEditorFocus(quill) {        console.log('editor focus!', quill)      },      onEditorReady(quill) {        console.log('editor ready!', quill)      },      onEditorChange({ quill, html, text }) {        console.log('editor change!', quill, html, text)        this.content = html      }    },    computed: {      editor() {        return this.$refs.myQuillEditor.quill      }    },    mounted() {      console.log('this is current quill instance object', this.editor)    }  }</script>

You may also like...

Leave a Reply

Your email address will not be published. Required fields are marked *