Open schuchowsky opened 8 years ago
If I remember correctly, this is a known issue with how the browser handles the selection.
cc @spicyj @hellendag -- Is there some ideas we have on solving this, based on the way it's done at FB?
Thanks @stopachka. I've extracted the code related to this issue from my project and created a public repository with it. Repository Demo Hope it helps!
@stopachka This sounds like the inline-block problem we discussed this week. I don't think we know of any good solution currently. On Facebook we implement emojis by rendering a wide space and adding the emoji image as a background image.
The lib that I'm using for emojis is emoji-mart. It renders a span with background-image for emojis. This causes the cursor to "disappear", once the cursor goes inside the emoji span. I'll create a PR for them, because I've already changed it to render a img instead of a span. As an img element, it solves the problem with the cursor disappearing, but the main problem persists.
Feel free to clone my repo and try it, and hopefully I can help you too. Thanks in advance.
Thanks for setting up that repository as an example - we would be open to PRs related to this. It sounds like other folks are running into this issue.
While waiting for a permanent fix for this issue, Here is what I implemented
let contentState = this.state.editorState.getCurrentContent();
let currentSelection = this.state.editorState.getSelection();
contentState = contentState.createEntity("EMOJI", "IMMUTABLE", emo.colons + "\u200A");
let emoEntityKey = contentState.getLastCreatedEntityKey();
let newContentState = Modifier.insertText(contentState, currentSelection, emo.colons + "\u200A", null, emoEntityKey);
let newEditorState = EditorState.push(this.state.editorState, newContentState, "insert-characters");
newEditorState = EditorState.push(this.state.editorState, newContentState, "insert-characters");
newEditorState = EditorState.moveFocusToEnd(newEditorState);
newEditorState = EditorState.forceSelection(newEditorState, newContentState.getSelectionAfter())
this.setState(editorState: newEditorState);
And then, the decorator strategy function:
function emojiMartRenderStrategy(contentBlock, callback, contentState) {
contentBlock.findEntityRanges(
character => {
const entityKey = character.getEntity();
return entityKey !== null && contentState.getEntity(entityKey).getType() === "EMOJI";
},
(start, end) => callback(start, end - 1)
);
}
notice that I'm calling the callback here with end - 1
. The reason for this is because I'm attaching a thin space character (\u+200A
) to the entity data when creating the emoji entity. This will make it possible for the cursor to be able to move in front of and behind the emoji.
For those who mind, here is how I render the emoji entity (using emoji-mart)
const EmojiMartIcon = props => {
let emoji = Emoji({
html: true,
set: "apple",
emoji: props.decoratedText,
size: props.emojiSize || 22
});
return emoji ? (
<span
style={{ width: 24, display: "inline-block" }}
dangerouslySetInnerHTML={{
__html: emoji
}}
/>
) : (
<>{props.decoratedText || props.emojiColons}</>
);
};
Hello, it's my first post here, so sorry in advance for any mistake.
I'm using Draft to create a message input component.
I'm using decorators to decorate "hashtags", and Entity to render emojis.
I'm using entities for emojis in order to set the text "IMMUTABLE", and be able to delete the whole text from the emoji at once, which is a pattern like this :emoji:
The problem is with the input focus when rendering the emojis. When the cursor is "in the front" of the emoji, it starts typing "behind" the emoji.
I've found that setting data-offset-key property into my emoji component improved a lot the control of the cursor,
DOM using data-offset-key: http://hnordt.d.pr/1ghat+
Problem with the cursor: http://hnordt.d.pr/1bk5d+
As you can see, when the cursor is in the next character after the emoji (Entity), it writes before the emoji. Only when navigating to the next character, it begins typing in the correct span.
Code when adding an emoji (emoji.colons is the emoji text ie ":emoji:"):
Decorator to transform emoji text in image:
Any ideas to solve that? Many thanks!