Currently I have a DraftJS editor like this:
<Editor
editorState={this.state.editorState}
handleKeyCommand={this.handleKeyCommand}
onChange={this.onChange}
placeholder="Write a tweet..."
ref="editor"
spellCheck={true}
/>
The construcor with state:
constructor(props) {
super(props);
const compositeDecorator = new CompositeDecorator([{
strategy: mentionStrategy,
component: MentionSpan,
}, {
strategy: hashtagStrategy,
component: HashtagSpan,
}, {
strategy: emojiStrategy,
component: EmojiSpan,
}]);
this.state = {
conversationActive: null,
editorState: EditorState.createEmpty(compositeDecorator),
};
this.focus = () => this.refs.editor.focus();
this.onChange = (editorState) => this.setState({editorState});
this.logState = () => console.log(this.state.editorState.toJS());
this.handleKeyCommand = () => 'not-handled';
}
I went as far as making a decorator strategy that matches a series of regex to figure out if a block is an emoji, like :D
, :(
, :|
, etc.
The problem is that I can't figure out how to "pass more props" to the element in the strategy or how to create an entity from the match...
Here's the strategy:
const findWithRegex = (regex, contentBlock, callback) => {
const text = contentBlock.getText();
let matchArr, start;
while ((matchArr = regex.exec(text)) !== null) {
start = matchArr.index;
callback(start, start + matchArr[0].length);
}
}
const emojiRegexes = [...];
export const emojiStrategy = (contentBlock, callback, contentState) => {
for (let i = 0; i < emojiRegexes.length; i++) {
findWithRegex(emojiRegexes[i].regex, contentBlock, callback);
}
}
export const EmojiSpan = (props) => {
return (
<span
className={styles.emoji}
data-offset-key={props.offsetKey}
>
{props.children}
</span>
);
};
Can anyone help me? Thanks!
PS: I can't seem to find a really in-depth documentation from draft-js the one on github only has shallow descriptions and dummy examples.
Managed to do what I wanted in a different manner, first, by replacing the text with unicode characters which in the future will be entities with metadata. The code is as follows:
onChange(editorState) {
const contentState = editorState.getCurrentContent();
let currentText = contentState.getBlockForKey(editorState.getSelection().getAnchorKey()).getText();
for (let i = 0; i < emojiRegexes.length; i++) {
currentText = currentText.replace(emojiRegexes[i].regex, () => emojiRegexes[i].unicode)
}
if (currentText === contentState.getBlockForKey(editorState.getSelection().getAnchorKey()).getText()) {
this.setState({ editorState });
return;
}
const updatedSelection = editorState.getSelection().merge({
anchorOffset: 0,
});
const edited = EditorState.push(
editorState,
Modifier.replaceText(
contentState,
updatedSelection,
currentText
),
'change-block-data'
);
this.setState({ editorState: edited });
}