Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

react-quill

Package Overview
Dependencies
Maintainers
1
Versions
49
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

react-quill - npm Package Compare versions

Comparing version 0.1.1 to 0.2.0

10

CHANGELOG.md
Changelog
=========
v0.2.0
------
- Fix React warnings about unique `key` props in toolbar (@Janekk).
- Sending `delta` and `source` from editor change events. Fixes #17.
- Rewritten uncontrolled and semi-controlled operation. Should fix #9, #10 and #14.
- Editor props can now be changed after mounting.
- Added callback for selection change event. Closes #12.
v0.1.1
------
- The pre-compiled distributable is not shipped with the NPM package anymore. Should fix [#2](https://github.com/zenoamaro/react-quill/issues/2).
- The pre-compiled distributable is not shipped with the NPM package anymore. Should fix #2.
- Sourcemaps are now emitted for both distributables, as separate files.

@@ -8,0 +16,0 @@ - Avoiding parsing Quill as it ships with a pre-built main.

2

package.json
{
"name": "react-quill",
"version": "0.1.1",
"version": "0.2.0",
"description": "The Quill rich-text editor as a React component.",

@@ -5,0 +5,0 @@ "author": "zenoamaro <zenoamaro@gmail.com>",

@@ -12,4 +12,2 @@ React-Quill ![](https://travis-ci.org/zenoamaro/react-quill.svg?branch=master)

**Warning**: The project is still in alpha stage. Use with caution.
1. [Quick start](#quick-start)

@@ -27,2 +25,8 @@ 2. [API reference](#api-reference)

~~~jsx
/*
Include `quill.base.css` to give the editor some basic styles it needs.
You can find the _base_ theme in the quill distribution or inside
`node_modules`.
*/
var React = require('react');

@@ -45,2 +49,8 @@ var ReactQuill = require('react-quill');

~~~jsx
/*
Include a theme like `quill.snow.css` and activate it in the
configuration like shown below. You can find the _snow_ theme in the
quill distribution or inside `node_modules`.
*/
var MyComponent = React.createClass({

@@ -123,3 +133,3 @@ /* ... */

`value`
: Value for the editor as a controlled component.
: Value for the editor as a controlled component. 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.

@@ -147,6 +157,9 @@ `defaultValue`

`onChange(value)`
`onChange(value, delta, source)`
: Called back with the new contents of the editor after change.
`onChangeSelection(range, source)`
: Called back with the new selected range, or null when unfocused.
Building and testing

@@ -173,2 +186,9 @@ --------------------

---------
#### v0.2.0
- Fix React warnings about unique `key` props in toolbar (@Janekk).
- Sending `delta` and `source` from editor change events. Fixes #17.
- Rewritten uncontrolled and semi-controlled operation. Should fix #9, #10 and #14.
- Editor props can now be changed after mounting.
- Added callback for selection change event. Closes #12.
#### v0.1.1

@@ -190,6 +210,4 @@ - The pre-compiled distributable is not shipped with the NPM package anymore. Should fix [#2](https://github.com/zenoamaro/react-quill/issues/2).

-------
- [ ] Support updates in editor life-cycle
- [ ] First-class support for modules
- [ ] Better API for custom controls?
- [ ] Delta updates

@@ -196,0 +214,0 @@

@@ -21,15 +21,30 @@ 'use strict';

propTypes: {
id: T.string,
className: T.string,
value: T.string,
id: T.string,
className: T.string,
style: T.object,
value: T.string,
defaultValue: T.string,
readOnly: T.bool,
toolbar: T.array,
formats: T.array,
styles: T.object,
theme: T.string,
readOnly: T.bool,
toolbar: T.array,
formats: T.array,
styles: T.object,
theme: T.string,
pollInterval: T.number,
onChange: T.func
onChange: T.func,
onChangeSelection: T.func
},
/*
Changing one of these props should cause a re-render.
*/
dirtyProps: [
'id',
'className',
'toolbar',
'formats',
'styles',
'theme',
'pollInterval'
],
getDefaultProps: function() {

@@ -44,19 +59,37 @@ return {

/*
Retrieve the initial value from either `value` (preferred)
or `defaultValue` if you want an un-controlled component.
We consider the component to be controlled if
whenever `value` is bein sent in props.
*/
isControlled: function() {
return 'value' in this.props;
},
getInitialState: function() {
return {};
return {
value: this.isControlled()
? this.props.value
: this.props.defaultValue
};
},
/*
Update only if we've been passed a new `value`.
This leaves components using `defaultValue` alone.
*/
componentWillReceiveProps: function(nextProps) {
var editor = this.state.editor;
// Update only if we've been passed a new `value`.
// This leaves components using `defaultValue` alone.
if ('value' in nextProps) {
if (nextProps.value !== this.props.value) {
this.setEditorContents(this.state.editor, nextProps.value);
// NOTE: Seeing that Quill is missing a way to prevent
// edits, we have to settle for a hybrid between
// controlled and uncontrolled mode. We can't prevent
// the change, but we'll still override content
// whenever `value` differs from current state.
if (nextProps.value !== this.getEditorContents()) {
this.setEditorContents(editor, nextProps.value);
}
}
// We can update readOnly state in-place.
if ('readOnly' in nextProps) {
if (nextProps.readOnly !== this.props.readOnly) {
this.setEditorReadOnly(editor, nextProps.readOnly);
}
}
},

@@ -78,3 +111,10 @@

shouldComponentUpdate: function(nextProps, nextState) {
// Never re-render or we lose the element.
// Check if one of the changes should trigger a re-render.
for (var i=0; i<this.dirtyProps.length; i++) {
var prop = this.dirtyProps[i];
if (nextProps[prop] !== this.props[prop]) {
return true;
}
}
// Never re-render otherwise.
return false;

@@ -123,7 +163,7 @@ },

getEditorContents: function() {
return this.props.value || this.props.defaultValue || '';
return this.state.value;
},
getClassName: function() {
return ['quill', this.props.className].join(' ');
getEditorSelection: function() {
return this.state.selection;
},

@@ -140,10 +180,12 @@

return [
// Quill modifies these elements in-place,
// so we need to re-render them every time.
QuillToolbar({
key:'toolbar',
ref:'toolbar',
key: 'toolbar-' + Math.random(),
ref: 'toolbar',
items: this.props.toolbar
}),
React.DOM.div({
key:'editor',
ref:'editor',
key: 'editor-' + Math.random(),
ref: 'editor',
className: 'quill-contents',

@@ -158,3 +200,5 @@ dangerouslySetInnerHTML: { __html:this.getEditorContents() }

return React.DOM.div({
className: this.getClassName(),
id: this.props.id,
style: this.props.style,
className: 'quill ' + this.props.className,
onChange: this.preventDefault },

@@ -165,10 +209,7 @@ this.renderContents()

/*
Updates the local state with the new contents,
executes the change handler passed as props.
*/
onEditorChange: function(value) {
if (value !== this.state.value) {
onEditorChange: function(value, delta, source) {
if (value !== this.getEditorContents()) {
this.setState({ value: value });
if (this.props.onChange) {
this.props.onChange(value);
this.props.onChange(value, delta, source);
}

@@ -178,2 +219,13 @@ }

onEditorChangeSelection: function(range, source) {
var s = this.getEditorSelection() || {};
var r = range || {};
if (r.start !== s.start || r.end !== s.end) {
this.setState({ selection: range });
if (this.props.onChangeSelection) {
this.props.onChangeSelection(range, source);
}
}
},
/*

@@ -180,0 +232,0 @@ Stop change events from the toolbar from

/*
React-Quill v0.1.0
React-Quill v0.2.0
https://github.com/zenoamaro/react-quill

@@ -4,0 +4,0 @@ */

@@ -18,17 +18,13 @@ 'use strict';

hookEditor: function(editor) {
var self = this;
editor.on('text-change', function(delta, source) {
if (self.onEditorChange) {
self.onEditorChange(editor.getHTML(), delta, source);
if (this.onEditorChange) {
this.onEditorChange(editor.getHTML(), delta, source);
}
});
},
}.bind(this));
updateEditor: function(editor, config) {
// NOTE: This tears the editor down, and reinitializes
// it with the new config. Ugly but necessary
// as there is no api for updating it.
this.destroyEditor(editor);
this.createEditor(config);
return editor;
editor.on('selection-change', function(range, source) {
if (this.onEditorChangeSelection) {
this.onEditorChangeSelection(range, source);
}
}.bind(this));
},

@@ -40,2 +36,7 @@

setEditorReadOnly: function(editor, value) {
value? editor.editor.disable()
: editor.editor.enable();
},
/*

@@ -49,3 +50,13 @@ Replace the contents of the editor, but keep

editor.setHTML(value);
editor.setSelection(sel);
if (sel) this.setEditorSelection(editor, sel);
},
setEditorSelection: function(editor, range) {
if (range) {
// Validate bounds before applying.
var length = editor.getLength();
range.start = Math.max(0, Math.min(range.start, length-1));
range.end = Math.max(range.start, Math.min(range.end, length-1));
}
editor.setSelection(range);
}

@@ -52,0 +63,0 @@

@@ -79,4 +79,5 @@ 'use strict';

renderSeparator: function(item) {
renderSeparator: function(key) {
return React.DOM.span({
key: key,
className:'ql-format-separator'

@@ -86,5 +87,5 @@ });

renderGroup: function(item) {
renderGroup: function(item, key) {
return React.DOM.span({
key: item.label,
key: item.label || key,
className:'ql-format-group' },

@@ -95,5 +96,5 @@ item.items.map(this.renderItem)

renderChoiceItem: function(item) {
renderChoiceItem: function(item, key) {
return React.DOM.option({
key: item.label || item.value,
key: item.label || item.value || key,
value:item.value },

@@ -104,5 +105,5 @@ item.label

renderChoices: function(item) {
renderChoices: function(item, key) {
return React.DOM.select({
key: item.label,
key: item.label || key,
className: 'ql-'+item.type },

@@ -113,5 +114,5 @@ item.items.map(this.renderChoiceItem)

renderAction: function(item) {
renderAction: function(item, key) {
return React.DOM.span({
key: item.label || item.value,
key: item.label || item.value || key,
className: 'ql-format-button ql-'+item.type,

@@ -122,8 +123,8 @@ title: item.label }

renderItem: function(item) {
renderItem: function(item, key) {
switch (item.type) {
case 'separator':
return this.renderSeparator();
return this.renderSeparator(key);
case 'group':
return this.renderGroup(item);
return this.renderGroup(item, key);
case 'font':

@@ -134,5 +135,5 @@ case 'align':

case 'background':
return this.renderChoices(item);
return this.renderChoices(item, key);
default:
return this.renderAction(item);
return this.renderAction(item, key);
}

@@ -139,0 +140,0 @@ },

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc