Code Monkey home page Code Monkey logo

react-quill's Introduction

ReactQuill Build Status npm npm downloads

A Quill component for React.

See a live demo or Codepen.


This is the documentation for ReactQuill v2 โ€” Previous releases: v1


๐Ÿ’ฏ ReactQuill v2

ReactQuill 2 is here, baby! And it brings a full port to TypeScript and React 16+, a refactored build system, and a general tightening of the internal logic.

We worked hard to avoid introducing any behavioral changes. For the vast majority of the cases, no migration is necessary at all. However, support for long-deprecated props, the ReactQuill Mixin, and the Toolbar component have been removed. Be sure to read the migration guide.

We expect this release to be a drop-in upgrade โ€“ย if that isn't the case, please file an issue with the v2 label.


Quick Start

With webpack or create-react-app

Make sure you have react and react-dom, and some way to load styles, like style-loader. See the documentation on themes for more information.

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} />;
}

With the browser bundle

<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>

Usage

Controlled mode caveats

In controlled mode, components are supposed to prevent local stateful changes, and instead only have them happen through onChange and value.

Because Quill handles its own changes, and does not allow preventing edits, ReactQuill has to settle for a hybrid between controlled and uncontrolled mode. It can't prevent the change, but will still override the content whenever value differs from current state.

If you frequently need to manipulate the DOM or use the Quill APIs imperatively, you might consider switching to fully uncontrolled mode. ReactQuill will initialize the editor using defaultValue, but won't try to reset it after that. The onChange callback will still work as expected.

Read more about uncontrolled components in the React docs.

Using Deltas

You can pass a Quill Delta, instead of an HTML string, as the value and defaultValue properties. 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.

Themes

The Quill editor supports themes. It includes a full-fledged theme, called snow, that is Quill's standard appearance, and a bubble theme that is similar to the inline editor on Medium. At the very least, the core theme must be included for modules like toolbars or tooltips to work.

To activate a theme, pass the name of the theme to the theme prop. Pass a falsy value (eg. null) to use the core theme.

<ReactQuill theme="snow" .../>

Then, import the stylesheet for the themes you want to use.

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. These stylesheets can be found in the Quill distribution, but for convenience they are also linked in ReactQuill's dist folder.

Here's an example using style-loader for Webpack, or create-react-app, that will automatically inject the styles on the page:

import 'react-quill/dist/quill.snow.css';

The styles are also available via CDN:

<link
  rel="stylesheet"
  href="https://unpkg.com/[email protected]/dist/quill.snow.css"
/>

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
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;

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 Example

Example Code
/*
 * 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')
);

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
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}
      />
    );
  }
}

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).

class MyComponent extends React.Component {

  render() {
    return (
      <ReactQuill>
        <div className="my-editing-area"/>
      </ReactQuill>
    );
  }

});

Upgrading to ReactQuill v2

Upgrading to ReactQuill v2 should be as simple as updating your dependency. However, it also removes support for long-deprecated props, the ReactQuill Mixin, and the Toolbar component.

Deprecated props

Support for the toolbar, styles, pollInterval Quill options has long disabled. Starting from this release, ReactQuill will not warn you anymore if you try using them.

ReactQuill Mixin

The ReactQuill Mixin allowed injecting the core functionality that made ReactQuill tick into your own components, and create deeply customized versions.

The Mixin has been considered an anti-pattern for a long time now, so we have decided to finalize its deprecation.

There is no upgrade path. If you have a use case that relied on the Mixin, you're encouraged to open an issue, and we will try to provide you with a new feature to make it possible, or dedicated support to migrate out of it.

Toolbar component

Quill has long provided built-in support for custom toolbars, which replaced ReactQuill's (quite inflexible) Toolbar component.

Use the Toolbar Module or the HTML Toolbar feature instead.

API reference

Exports

// ES6
import ReactQuill, { Quill } from 'react-quill';

// CommonJS
const ReactQuill = require('react-quill');
const { Quill } = ReactQuill;

Quill : The Quill namespace on which you can call register.

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

View this example on 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 : 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
const editor = this.reactQuillRef.getEditor();
const unprivilegedEditor = this.reactQuillRef.makeUnprivilegedEditor(editor);
// You may now use the unprivilegedEditor proxy methods
unprivilegedEditor.getText();

The unprivileged editor

During events, ReactQuill will make a restricted subset of the Quill API available as the editor argument. 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 build libs, types and bundles:

npm build  # or watch

You can also run the automated test suite:

npm test

More tasks are available as package scripts:

Script Description
npm run build Builds lib and browser bundle
npm run watch Rebuilds on source code changes
npm run test Runs unit tests and coverage
npm run clean Cleans build artifacts
npm run demo Serves a simple ReactQuill test application

Browser support

Please check the browser support table for the upstream Quill dependency. The ReactQuill distributable itself is ES5-compatible.

Changelog

Full changelog

Contributors

ReactQuill would not be where it is today without the contributions of many people, which we are incredibly grateful for:

  • @zenoamaro (maintainer)
  • @alexkrolick (maintainer)
  • @g12i
  • @clemmy
  • @asiniy
  • @webcarrot
  • @druti
  • @e-jigsaw
  • @zhang-z
  • @Sajam
  • @0bird512
  • @jacktrades
  • @1000hz
  • @kkerr1
  • @csk157
  • @Janekk
  • @AndyTheGiant
  • @chrismcv
  • @wouterh
  • @tdg5
  • @jrmmnr
  • @l3kn
  • @rpellerin
  • @sandbochs
  • @wouterh
  • @MattKunze

License

The MIT License (MIT)

Copyright (c) 2020, zenoamaro [email protected]

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

react-quill's People

Contributors

ajaska avatar alexkrolick avatar andylnd avatar asiniy avatar bakkerjoeri avatar bird512 avatar bobrafie avatar charrondev avatar chrismcv avatar clemmy avatar clinyong avatar csk157 avatar daggmano avatar dependabot[bot] avatar druti avatar janekk avatar jdhuntington avatar jetzhou avatar johnstrick avatar kairxa avatar kkerr1 avatar mikecousins avatar msc117 avatar pjstaab avatar rockwotj avatar rpellerin avatar sajam avatar sandbochs avatar thepaulmcbride avatar zenoamaro avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

react-quill's Issues

Issue with getEditor() in componentDidMount()

I am trying to load earlier saved HTML content into react-quill.

Example 3 (setting content using dangerouslySetInnerHTML) isn't working for me.

As an alternative, I tried to access editor instance in componentDidMount() and set the HTML content using this.refs.quill.getEditor().setHTML({this.props.content});

However, getEditor() returns 'undefined' in componentDidMount()

If I use the same getEditor() later, say in an onChange event, i am able to access the underlying editor.

For now, i am accessing the DOM via getDOMNode() to set the initial HTML content.

It will be great if you can look into it.

live demo not works well

I remember it works well but today is not.
I use chrome which version is 46.I can't set color or size of fonts.when I select fonts and click color.it will unselect fonts,so I can't set it.

Only a ReactOwner can have refs.

React (with addons) v0.13.3

Code

let React = require('react');
let ReactQuill = require('react-quill');

let Redactor = React.createClass({

    getInitialState: function() {
        return {
            value: defaultContent
        };
    },

    render: function() {
        return (
            <ReactQuill
                        value={this.state.value}>
                <ReactQuill.Toolbar key="toolbar"
                                    ref="toolbar"
                                    items={ReactQuill.Toolbar.defaultItems} />
                <div key="editor"
                     ref="editor"
                     className="quill-contents"
                     dangerouslySetInnerHTML={{__html:this.state.value}} />
            </ReactQuill>
        );
    }
});

React.render(<Redactor/>,
    document.getElementById('redactor')
);

Error

Uncaught Error: Invariant Violation: addComponentAsRefTo(...): Only a ReactOwner can have refs. This usually means that you're trying to add a ref to a component that doesn't have an owner (that is, was not created inside of another component's `render` method). Try rendering this component inside of a new top-level component which will hold the ref.

s.th. wrong with the toolbar

hi,

I just tried to use react-quill, but something is not quite right with the toolbar:

screen shot 2015-05-28 at 11 07 52

also I get this console warning:

Warning: Each child in an array or iterator should have a unique "key" prop. Check the render method of Quill Toolbar. See https://fb.me/react-warning-keys for more information.

here's how I use it:

<ReactQuill
    ref='bio'
    value={this.state.form.bio}
    onChange={ function(value) { that.handleChangeRichtext('bio', value) } }
/>

not sure what I'm doing wrong here...

Selection lost on focus lost

This project is great. However, I'm experiencing a loss of my selections on selected text editor whenever I move my mouse to the toolbar.
Basically,

  1. I select some text in the editor area.
  2. I click the Bold icon to make them bold
  3. Nothing happens since my selection is lost
  4. I continue typing and all subsequent text will appear bold

Tested on Chrome 47.0.2526.80 m

Running npm install for the dev dependencies fails on Node v4.2.1

Older versions of jsdom have issues building on Node 4.x. Upgrading the jsdom dependency to "jsdom": "^7.0.1", fixes the problem.

However, it seems that as of 7.0.0, jsdom only supports Node 4.x or newer, and apparently the 3.x series of jsdom (which does support < Node 4.x) is now unmaintained.

Since I'm new to this project, and don't know what build environments you need to support, I'll leave the fix for this one up to the maintainers.

Third example is not working

Third example is not working because this.refs.editor and this.refs.toolbar is undefined in the component.js.

No styles in distribution

Can't seem to find the quill.base.css or snow theme files anywhere in the node_modules package folder or the github repository.

onKeyUp, onKeyDown, onKeyPress not working

I've tried passing a callback into these 3 props, as stated in the react-quill API, and haven't seen anything get returned. I checked in component.js and I see that at line 225 it calls onChange (which I do receive updates for). I need onKeyUp to register that a user has hit the enter key but I don't see onKeyUp, onKeyDown, or onKeyPress being used anywhere. Is there anyway to get the key code for enter other than these 3 functions?

Unable to get react-quill 0.3.0 working with react 0.12.1

I'm running React.js 0.12.1 and upgrading to 0.13 or 0.14 is not possible at this time.

I tried installing react-quill via "npm install react-quill". Version 0.3.0 was installed and, looking at react-quill\package.json, the devDependency for react is "^0.12.0".

When I use react-quill as follows in my React component, I get the warning, "Warning: Something is calling a React component directly. Use a factory or JSX instead" from react-with-addons.js, followed by the error _"Uncaught TypeError: Cannot read property '_reactAutoBindMap' of null" from ReactClass.sj.

var ReactQuill = require('react-quill');
var MyComponent = React.createClass({
    render: function() {
        return <ReactQuill value="hi" />;
    }
);

As you can see, I am using JSX.

I saw some discussion on removing React 0.12 support at some point. Does react-quill 0.3.0 still support React 0.12?

Default font sizes for "Normal" and "Smaller" swapped

The current (caaf6ef) default values for the font sizes are:

        { label:'Size', type:'size', items: [
            { label:'Normal',  value:'10px' },
            { label:'Smaller', value:'13px' },
            { label:'Larger',  value:'18px' },
            { label:'Huge',    value:'32px' }
        ]}

I suspect "Normal" should be 13px and "Smaller" then 10px.

Ideally the order would still be "Smaller", "Normal", "Larger", "Huge", but it looks like the first element is assumed to be "Normal"? I haven't investigated this, but it'd be nice if above were the default option order and "Normal" were the default selection.

Unless I use my own stylesheet, styles won't work

The problem:
If I do not manually include the stylesheet in my application.scss, the editor shows as follows:
screen shot 2015-09-17 at 11 41 41 am

What's strange is that after including it in my application.scss
screen shot 2015-09-17 at 11 43 09 am
Styles do load, but collide:
screen shot 2015-09-17 at 11 47 56 am

I had in mind a couple of ways of fixing this.

By including only the dist/quill.js like so:
import Editor from "react-quill/node_modules/quill/dist/quill.js";

but throws the following error:
screen shot 2015-09-17 at 11 50 45 am

The other is to get rid of the styles in dist so I can have more control over them, but that would require to fork and use that which does not seem like the best idea

Any suggestions or advice on this issue @zenoamaro , I really appreciate your help ๐Ÿ™

How can I determine if the enter key was pressed?

The onTextChange function provides a delta argument that gives you the last keystroke.

If I hit the enter key, the delta returns "โ†ต", but I can't query for that in my JS code.

Is there another way to query for certain key strokes?

Removing Toolbar

Is there currently a way to remove the toolbar through props? I'd like to have the toolbar available in certain instances but not others.

Adding Image Upload Icon fails for me

<QuillReact modules={{ 'image-tooltip': true }} theme={"snow"} value={this.state.message} onChange={this._handleTextChange} />

Unless I am doing something wrong, this should add the image icon to the end of the toolbar. But it seems to just show the toolbar but without image icon.
Thanks.

A ton of warning in browser console

I use react-quill,it works nice but as title said.I get lots of warnings when I use react-quill with material-ui. material-ui has fixed it so I hope react-quill will fixed it too.
Thanks!

react version:0.14.2
material-ui version:0.13.3
react-quill 0.3.0

as below

Warning: onDismiss will be removed in favor of explicitly setting open and can be replaced by onRequestClose

Warning: ReactDOMComponent: Do not access .getDOMNode() of a DOM node; instead, use the node directly. This DOM node was rendered by Quill.

Handling critical dependencies

I get the following warning
WARNING in ./~/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

WebPack related error

Hi, @zenoamaro I got an error with webpack.

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

Related code is

require('../../../../node_modules/react-quill/node_modules/quill/dist/quill.base.css');
require('../../../../node_modules/react-quill/node_modules/quill/dist/quill.snow.css');

var styles = {
      '.quill': {
          'border': '1px solid #d5d5d5'
      },
      '.ql-toolbar': {
          'box-shadow': '0 1px 10px rgba(0, 0, 0, .1)'
      },
      '.quill-contents ': {
          'height': '250px'
      }
  };

<ReactQuill
    styles={styles}
    theme="snow"
    value={data.description}
    onChange={this.onTextChange}/>

Hope React-quill can support customized className for Toolbar items

Hi, ๐Ÿ˜ƒ

Currently, react-quill use 'ql-'+item.type as the class name of item, which in some cases is inconvenient for customizing.

For example, I use icomoon to create icons. However, it gives me icons with class name such as icon-blablabla. So I have to modify these class name from icon-blablabla to ql-blablabla manually.
Therefore I hope that react-quill can support customized class name for items. Like:

    renderChoices: function(item, key) {
        return React.DOM.select({
            key: item.label || key,
            title: item.label,
            className: 'ql-'+item.type + ' ' + item.className },     <---- customized class name
            item.items.map(this.renderChoiceItem)
        );
    },

Thanks ๐Ÿ˜Š

npm test fails

After working around #45, running npm test fails.

React 0.12

The dev dependencies require React 0.12, however the component.js file throws an error that React addons are not provided.

Updating the React dependency to "react": "^0.13.0", fixes this, but obviously has the implication that React 0.12 is not supported by the tests.

Test Coverage

Once I did get the test run to complete successfully, it then failed the code coverage threshold:

/react-quill$ npm test
...
Coverage: 20%
Code coverage below threshold: 20 < 50

Which makes sense, given that the test files seem to only have TODOs in them. :)

Adding a config section to the package.json "fixes" this (even if it is cheating a bit).

  "config": {
    "travis-cov": {
      "threshold": 1
    }
  },

I have a branch here that fixes these things if you'd like me to submit a pull request.

Quill component isn't exposed yet

I don't think the Quill namespace is exposed yet. I noticed that the change that exposes the Quill namespace happened a month ago while the latest dist is 2 months old.

I struggled a bit with the browser throwing up 'undefined' when accessing the component. It'll be great if you can check this out.

Awesome work with the editor. I am a convert from TinyMCE to Quill.

lastest versions

Both of the main dependencies, quill and react, are behind in their respective versions.

ql-editor loses focus after one keypress

I'm having an issue where when I press a key the element with .ql-editor loses focus and I can no longer type. This occurs whenever i have an onChange={this.handleEditorChange} prop added. the following example is:

<div className="small-12 columns" style={{border:"1px solid black", padding:"0"}}>

  <ReactQuill
    theme="snow"
    items={ReactQuill.Toolbar.defaultItems}
    className="small-12 columns"
    onChange={this.handleEditorChange}
    defaultValue={this.state.text}
    style={styles.getStyles(['no_side_padding'])}
      styles={{
        ".quill-toolbar":{
          'border-bottom':'1px solid black'
        },
        ".ql-editor":{
          'min-height': '15em'
        }
      }}
    />
</div>

the handleEditorChange is:

handleEditorChange: function(value, delta, source){
        this.setState({
            text: value
        });
}

i suspect that its because setState triggers a re-render, but I don't have any issues with my native form components.

Suggestions?

If input quickly editor does some loops with chars (in controlled mode)

When using react-quill component in controlled mode (roundtrip with onChange event and passing back the value through props) and input quickly it will fall into an infinite loop constantly updating editor states (e.g.: <div>abcd</div> updated to <div>abcde</div> back and forth)

<ReactQuill value={project.description}
  theme="snow" onChange={this.onEditorChange.bind(this, 'description')} />

If the uncontrolled mode is used (defaultValue instead of value) the problem goes away.

Image toolbar button as default

Just curious if there's a reason why the image toolbar button is not included by default. I have it added as a default on a local branch, it sits just to the right of the link button. If you think this is something that SHOULD be added as default I can create a pull request for it.

specify href target

Not sure if this is a Quill question or react-quill. This isn't an issue but a question.

I just can't figure out how I'd apply target="_blank" by default to all links generated with react-quill. I can see the formats section, which I'd think I could do something like:

formats = [
  "bold",
  {name: "link", tag: "a", type: "link", target: "_blank"}
];

But I obviously don't understand the quill api properly. Any help ?

How do I focus()?

Hi

I'm trying to set the input focus to my react-quill component.

I tried the following but it doesn't seem to do anything (it works for a normal input field though).

componentDidMount: function(){
  React.findDOMNode(this.refs.quillRef).focus();
},

Any help would be super!

Adding custom formats causes error

var config = [
  "list",
  "bullet",
  "bold",
  "italic",
  { name: "h1", tag: "H1", prepare: "heading", type: "line" },
  { name: "h2", tag: "H2", prepare: "heading", type: "line" },
  { name: "h3", tag: "H3", prepare: "heading", type: "line" }
]

<ReactQuill
   ...
   formats={config}
/>

Causes:

TypeError: Cannot read property 'tag' of undefined

The error code is:

Normalizer.prototype.addFormat = function(config) {
    if (config.tag != null) {
      this.whitelist.tags[config.tag] = true;
    }
    if (config.parentTag != null) {
      this.whitelist.tags[config.parentTag] = true;
    }
    if (config.style != null) {
      return this.whitelist.styles[config.style] = true;
    }
};

Doesn't work with browserify

If i require the module with browserify I get issues:

Fatal error: Invalid mapping: {"generated":{"line":14084,"column":7},"source":"webpack:///webpack/universalModuleDefinition","original":{},"name":null}

It works if i require the raw file from the src directory: require("react-quill/src")

React 0.14 support

Any plans for this? I might attempt it in a week or so, if you don't have any plans. I'm actually already using react-quill in 0.14, and other than a few warnings for deprecations, there seems to be no breaking changes.

dangerouslySetInnerHTML error

So I've tried to use the component. But I get the error about the wrong usage of the property dangerouslySetInnerHTML.
I've setup an app showing this.
You can just follow the README to fire it up and see the error in the browser's console.

Any idea what might be wrong?

TypeError: html is undefined

If you don't pass a value property to <ReactQuill /> it produces an error: TypeError: html is undefined.

This behavior is present in the latest commit to master (d68d530) but not in the currently released version (0.2.2).

The problem seems to originate from here where this.props.value is used without checking if it exists. this.setEditorContents(editor, this.props.value || ''); seems to fix this issue.

I'm not sure if this is by design, or if this is a regression.

Custom fonts

Hi,

Just wondering if there's an existing way to add custom fonts?

Thanks

Can't pass in custom toolbar

I'm trying to wrap react-quill in my own components, and use a custom toolbar via the toolbar prop to ReactQuill. There are some issues that combine to prevent me from doing so.

When my component does setState, ReactQuill's shouldComponentUpdate gets called. The equality on this line however will return true on the toolbar prop, causing ReactQuill to update when it should not.

When it is doing this update, the component's state fails to include an editor property. Therefore when it rerenders, destroyEditor fails, it can't call .destroy of undefined.

Any thoughts on this?

webpack build issue

WARNING in .//react-quill//quill/dist/quill.js
Critical dependencies:
1:538-546 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 1:538-546

How can I get the Quill object?

The Quill API is very rich and provides and provides a variety of useful functions. How can I get my hands on the Quill object? http://quilljs.com/docs/api/#quillprototypegettext

I have the html value that Quill outputs ex:

"<div><span style="color: rgb(230, 0, 0);">This is red; </span> This is not.</div>"

I need to extract the text value which can be done through Quill.prototype.getText() to get...
"This is red; this is not."

How can I edit markup in editor?

Hi,

I'd like to tweak the markup of the react-quill editor after a user hits the enter key. Specifically, I'd like to add a span tag inside of the last sentence a user has entered.

I tried using the method dangerouslySetInnerHTML(), but it doesn't work. The react-quill component strips out any markup I specifically try to inject into the editor.

Is there any way for me to override this?

Invariant Violation: ReactMount: Two valid but unequal nodes with the same `data-reactid`

Hello,

I have noticed a bunch of errors when using the editor with Snow theme, happening when, for example, moving mouse over dropdown type toolbar items:

Uncaught Error: Invariant Violation: ReactMount: Two valid but unequal nodes with the same `data-reactid`: .0.1.0.0.0.$WelcomeText.$toolbar.$Formats.$Size

Uncaught Error: Invariant Violation: ReactMount: Two valid but unequal nodes with the same `data-reactid`: .0.1.0.0.0.$WelcomeText.$toolbar.$Formats.$Size

Uncaught Error: Invariant Violation: ReactMount: Two valid but unequal nodes with the same `data-reactid`: .0.1.0.0.0.$WelcomeText.$toolbar.$Formats.$Font

Uncaught Error: Invariant Violation: ReactMount: Two valid but unequal nodes with the same `data-reactid`: .0.1.0.0.0.$WelcomeText.$toolbar.$Formats.$Font
<span class="ql-format-group" data-reactid=".0.1.0.0.0.$WelcomeText.$toolbar.$Formats">
  <span class="ql-font ql-picker" data-reactid=".0.1.0.0.0.$WelcomeText.$toolbar.$Formats.$Font"><span class="ql-picker-label" data-value="sans-serif">Sans Serif</span><span class="ql-picker-options"><span data-value="sans-serif" class="ql-picker-item ql-selected">Sans Serif</span><span data-value="serif" class="ql-picker-item">Serif</span><span data-value="monospace" class="ql-picker-item">Monospace</span></span></span>
  <select class="ql-font" data-reactid=".0.1.0.0.0.$WelcomeText.$toolbar.$Formats.$Font" style="display: none;">
    <option value="sans-serif" data-reactid=".0.1.0.0.0.$WelcomeText.$toolbar.$Formats.$Font.$Sans Serif">Sans Serif</option>
    <option value="serif" data-reactid=".0.1.0.0.0.$WelcomeText.$toolbar.$Formats.$Font.$Serif">Serif</option>
    <option value="monospace" data-reactid=".0.1.0.0.0.$WelcomeText.$toolbar.$Formats.$Font.$Monospace">Monospace</option>
  </select>
  <span class="ql-format-separator" data-reactid=".0.1.0.0.0.$WelcomeText.$toolbar.$Formats.1"></span><span class="ql-size ql-picker" data-reactid=".0.1.0.0.0.$WelcomeText.$toolbar.$Formats.$Size"><span class="ql-picker-label" data-value="10px">Normal</span><span class="ql-picker-options"><span data-value="10px" class="ql-picker-item ql-selected">Normal</span><span data-value="13px" class="ql-picker-item">Smaller</span><span data-value="18px" class="ql-picker-item">Larger</span><span data-value="32px" class="ql-picker-item">Huge</span></span></span>
  <select class="ql-size" data-reactid=".0.1.0.0.0.$WelcomeText.$toolbar.$Formats.$Size" style="display: none;">
    <option value="10px" data-reactid=".0.1.0.0.0.$WelcomeText.$toolbar.$Formats.$Size.$Normal">Normal</option>
    <option value="13px" data-reactid=".0.1.0.0.0.$WelcomeText.$toolbar.$Formats.$Size.$Smaller">Smaller</option>
    <option value="18px" data-reactid=".0.1.0.0.0.$WelcomeText.$toolbar.$Formats.$Size.$Larger">Larger</option>
    <option value="32px" data-reactid=".0.1.0.0.0.$WelcomeText.$toolbar.$Formats.$Size.$Huge">Huge</option>
  </select>
  <span class="ql-format-separator" data-reactid=".0.1.0.0.0.$WelcomeText.$toolbar.$Formats.3"></span><span class="ql-align ql-picker" data-reactid=".0.1.0.0.0.$WelcomeText.$toolbar.$Formats.$Alignment"><span class="ql-picker-label" data-value="center"></span><span class="ql-picker-options"><span data-value="center" class="ql-picker-item ql-selected"></span><span data-value="left" class="ql-picker-item"></span><span data-value="right" class="ql-picker-item"></span><span data-value="justify" class="ql-picker-item"></span></span></span>
  <select class="ql-align" data-reactid=".0.1.0.0.0.$WelcomeText.$toolbar.$Formats.$Alignment" style="display: none;">
    <option value="center" data-reactid=".0.1.0.0.0.$WelcomeText.$toolbar.$Formats.$Alignment.$center"></option>
    <option value="left" data-reactid=".0.1.0.0.0.$WelcomeText.$toolbar.$Formats.$Alignment.$left"></option>
    <option value="right" data-reactid=".0.1.0.0.0.$WelcomeText.$toolbar.$Formats.$Alignment.$right"></option>
    <option value="justify" data-reactid=".0.1.0.0.0.$WelcomeText.$toolbar.$Formats.$Alignment.$justify"></option>
  </select>
</span>

I think that it happens because the theme adds with customised spans for each select and copies all their attributes.

This does not affect the functionality of the plugin it seems.

Uncaught TypeError: Cannot read property 'destroy' of undefined

in mixin.js:
destroyEditor: function(editor) {
editor.destroy();
},

if the DOM's changed (the editor had been removed) , I get the following error in Chrome: Uncaught TypeError: Cannot read property 'destroy' of undefined. Probably need to add a null check

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.