Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,8 @@
"quill": "^1.3.7"
},
"peerDependencies": {
"react": "^16 || ^17 || ^18",
"react-dom": "^16 || ^17 || ^18"
"react": "^16 || ^17 || ^18 || ^19",
"react-dom": "^16 || ^17 || ^18 || ^19"
},
"devDependencies": {
"@types/chai": "^4.2.11",
Expand Down
24 changes: 14 additions & 10 deletions src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ https://github.com/zenoamaro/react-quill
*/

import React from 'react';
import ReactDOM from 'react-dom';
import isEqual from 'lodash/isEqual';

import Quill, {
Expand Down Expand Up @@ -145,9 +144,12 @@ class ReactQuill extends React.Component<ReactQuillProps, ReactQuillState> {
editor?: Quill

/*
Reference to the element holding the Quill editing area.
Reference to the element holding the Quill editing area. Typed as `any`
because the editing area may be an arbitrary host element supplied through
`children` and cloned with `React.cloneElement`, so its concrete element
type is not known at compile time.
*/
editingArea?: React.ReactInstance | null
editingAreaRef = React.createRef<any>()

/*
Tracks the internal value of the Quill editor
Expand Down Expand Up @@ -433,16 +435,20 @@ class ReactQuill extends React.Component<ReactQuillProps, ReactQuillState> {
}

getEditingArea(): Element {
if (!this.editingArea) {
throw new Error('Instantiating on missing editing area');
}
const element = ReactDOM.findDOMNode(this.editingArea);
const element = this.editingAreaRef.current;
if (!element) {
throw new Error('Cannot find element for editing area');
}
if (element.nodeType === 3) {
throw new Error('Editing area cannot be a text node');
}
if (!(element instanceof Element)) {
throw new Error(
'Editing area must be a DOM element. When passing `children` to ' +
'ReactQuill, the child must render a host element such as `<div>` ' +
'or `<pre>` that can receive a ref.'
);
}
return element as Element;
}

Expand All @@ -455,9 +461,7 @@ class ReactQuill extends React.Component<ReactQuillProps, ReactQuillState> {

const properties = {
key: generation,
ref: (instance: React.ReactInstance | null) => {
this.editingArea = instance
},
ref: this.editingAreaRef,
};

if (React.Children.count(children)) {
Expand Down
24 changes: 24 additions & 0 deletions test/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,30 @@ describe('<ReactQuill />', function() {
expect(wrapper.getDOMNode().querySelector('div#venus')).not.to.be.null;
});

it('resolves the editing area to a DOM element', () => {
const wrapper = mountReactQuill();
const editingArea = wrapper.instance().getEditingArea();
expect(editingArea.nodeType).to.equal(1);
expect(wrapper.getDOMNode().contains(editingArea)).to.equal(true);
});

it('resolves a custom editing area to the element that was provided', () => {
const div = React.createFactory('div');
const wrapper = mountReactQuill({}, div({ id: 'venus' }));
const editingArea = wrapper.instance().getEditingArea();
expect(editingArea.id).to.equal('venus');
});

it('regenerates the editing area reference on a dirty prop change', () => {
const wrapper = mountReactQuill();
const before = wrapper.instance().getEditingArea();
wrapper.setProps({ theme: 'bubble' });
const after = wrapper.instance().getEditingArea();
expect(after.nodeType).to.equal(1);
expect(after).not.to.equal(before);
expect(wrapper.getDOMNode().contains(after)).to.equal(true);
});

/**
* This can't be tested with the current state of JSDOM.
* The selection functions have been shimmed in this test suite,
Expand Down