Ensure emoji picker can insert without composition box focus

This commit is contained in:
Chris Svenningsen 2020-11-02 14:07:52 -08:00 committed by Evan Hahn
parent b7a1ddf628
commit ff18063f89
2 changed files with 31 additions and 17 deletions

View File

@ -8,7 +8,7 @@ import ReactQuill from 'react-quill';
import classNames from 'classnames';
import emojiRegex from 'emoji-regex';
import { Manager, Reference } from 'react-popper';
import Quill, { KeyboardStatic } from 'quill';
import Quill, { KeyboardStatic, RangeStatic } from 'quill';
import Op from 'quill-delta/dist/Op';
import { EmojiBlot, EmojiCompletion } from '../quill/emoji';
@ -89,6 +89,10 @@ export const CompositionInput: React.ComponentType<Props> = props => {
const [emojiCompletionElement, setEmojiCompletionElement] = React.useState<
JSX.Element
>();
const [
lastSelectionRange,
setLastSelectionRange,
] = React.useState<RangeStatic | null>(null);
const emojiCompletionRef = React.useRef<EmojiCompletion>();
const quillRef = React.useRef<Quill>();
@ -168,19 +172,20 @@ export const CompositionInput: React.ComponentType<Props> = props => {
const range = quill.getSelection();
if (range === null) {
const insertionRange = range || lastSelectionRange;
if (insertionRange === null) {
return;
}
const emoji = convertShortName(e.shortName, e.skinTone);
const delta = new Delta()
.retain(range.index)
.delete(range.length)
.retain(insertionRange.index)
.delete(insertionRange.length)
.insert({ emoji });
quill.updateContents(delta, 'user');
quill.setSelection(range.index + 1, 0, 'user');
quill.setSelection(insertionRange.index + 1, 0, 'user');
};
const reset = () => {
@ -433,6 +438,15 @@ export const CompositionInput: React.ComponentType<Props> = props => {
quill.setSelection(quill.getLength(), 0);
});
quill.on(
'selection-change',
(newRange: RangeStatic, oldRange: RangeStatic) => {
// If we lose focus, store the last edit point for emoji insertion
if (newRange === null) {
setLastSelectionRange(oldRange);
}
}
);
quillRef.current = quill;
emojiCompletionRef.current = quill.getModule('emojiCompletion');
}

View File

@ -14544,15 +14544,6 @@
"rule": "React-useRef",
"path": "ts/components/CompositionInput.js",
"line": " const emojiCompletionRef = React.useRef();",
"lineNumber": 34,
"reasonCategory": "falseMatch",
"updated": "2020-10-26T19:12:24.410Z",
"reasonDetail": "Doesn't refer to a DOM element."
},
{
"rule": "React-useRef",
"path": "ts/components/CompositionInput.js",
"line": " const quillRef = React.useRef();",
"lineNumber": 35,
"reasonCategory": "falseMatch",
"updated": "2020-10-26T19:12:24.410Z",
@ -14561,8 +14552,17 @@
{
"rule": "React-useRef",
"path": "ts/components/CompositionInput.js",
"line": " const scrollerRef = React.useRef(null);",
"line": " const quillRef = React.useRef();",
"lineNumber": 36,
"reasonCategory": "falseMatch",
"updated": "2020-10-26T19:12:24.410Z",
"reasonDetail": "Doesn't refer to a DOM element."
},
{
"rule": "React-useRef",
"path": "ts/components/CompositionInput.js",
"line": " const scrollerRef = React.useRef(null);",
"lineNumber": 37,
"reasonCategory": "usageTrusted",
"updated": "2020-10-26T19:12:24.410Z",
"reasonDetail": "Used with Quill for scrolling."
@ -14571,7 +14571,7 @@
"rule": "React-useRef",
"path": "ts/components/CompositionInput.js",
"line": " const propsRef = React.useRef(props);",
"lineNumber": 37,
"lineNumber": 38,
"reasonCategory": "falseMatch",
"updated": "2020-10-26T19:12:24.410Z",
"reasonDetail": "Doesn't refer to a DOM element."
@ -15116,4 +15116,4 @@
"reasonCategory": "falseMatch",
"updated": "2020-09-08T23:07:22.682Z"
}
]
]