I'm using a draft.js editor in such a way that I need to update the decorator and also the props of the component it renders on the fly inside onChange
. This to mark parts of the text with a background color.
I can almost get this working, but there's a weird bug where among other things it is not possible to select the character immediately after one of the decorated components.
Here is a minimal (artificial) example to reproduce the bug:
import React from 'react';
import { CompositeDecorator, Editor, EditorState } from 'draft-js';
const Marked = ({ children, background }) => <span style={{ background }}>{children}</span>;
class TestEditor extends React.Component {
constructor(props) {
super(props);
this.state = { editorState: EditorState.createEmpty() };
this.handleChange = this.handleChange.bind(this);
}
handleChange(editorState) {
const markers = [{ from: 3, to: 7 }, { from: 12, to: 15 }];
const strategy = (contentBlock, callback) => {
const text = contentBlock.getText();
markers.forEach(({ from, to }) => {
if (text.length >= to) callback(from, to);
});
};
const decorator = new CompositeDecorator([
{ strategy, component: (props) => <Marked {...props} background="#00ff2a1a" /> },
]);
const newEditorState = EditorState.set(editorState, { decorator });
this.setState({ editorState: newEditorState });
}
render() {
const { editorState } = this.state;
return <Editor editorState={editorState} onChange={this.handleChange} />;
}
}
export default TestEditor;
This will be a text input where the text at position 3 - 7 and 12 - 15 has a green background (if it exists).
If I now for example write aaabbbbccc
it is not possible to select the first c
. Using the mouse it is selected until I release the mouse button; using the keyboard it doesn't appear to be selected at all (it might be momentarily).
If I use a static component with no new input in the handleChange
method it works ok: const decorator = new CompositeDecorator([{ strategy, component: Marked }]);
. However this doesn't fit my use case.
Any suggestions?
In the end it turns out I can do what I need with draft's entities
, probably with much better performance