Made the emoji autocomplete aligned with the :word
This commit is contained in:
parent
3436283165
commit
bb9a7113f1
2 changed files with 45 additions and 5 deletions
|
@ -6800,7 +6800,7 @@ button.module-image__border-overlay:focus {
|
||||||
padding: 0;
|
padding: 0;
|
||||||
margin-bottom: 6px;
|
margin-bottom: 6px;
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
z-index: $z-index-popup;
|
z-index: $z-index-above-popup;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
|
||||||
&--scroller {
|
&--scroller {
|
||||||
|
|
|
@ -4,11 +4,12 @@
|
||||||
import Quill from 'quill';
|
import Quill from 'quill';
|
||||||
import Delta from 'quill-delta';
|
import Delta from 'quill-delta';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import _ from 'lodash';
|
import _, { isNumber } from 'lodash';
|
||||||
|
|
||||||
import { Popper } from 'react-popper';
|
import { Popper } from 'react-popper';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import { createPortal } from 'react-dom';
|
import { createPortal } from 'react-dom';
|
||||||
|
import type { VirtualElement } from '@popperjs/core';
|
||||||
import type { EmojiData } from '../../components/emoji/lib';
|
import type { EmojiData } from '../../components/emoji/lib';
|
||||||
import {
|
import {
|
||||||
search,
|
search,
|
||||||
|
@ -19,7 +20,7 @@ import {
|
||||||
import { Emoji } from '../../components/emoji/Emoji';
|
import { Emoji } from '../../components/emoji/Emoji';
|
||||||
import type { EmojiPickDataType } from '../../components/emoji/EmojiPicker';
|
import type { EmojiPickDataType } from '../../components/emoji/EmojiPicker';
|
||||||
import { getBlotTextPartitions, matchBlotTextPartitions } from '../util';
|
import { getBlotTextPartitions, matchBlotTextPartitions } from '../util';
|
||||||
import { sameWidthModifier } from '../../util/popperUtil';
|
import * as log from '../../logging/log';
|
||||||
|
|
||||||
const Keyboard = Quill.import('modules/keyboard');
|
const Keyboard = Quill.import('modules/keyboard');
|
||||||
|
|
||||||
|
@ -265,8 +266,47 @@ export class EmojiCompletion {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// a virtual reference to the text we are trying to auto-complete
|
||||||
|
const reference: VirtualElement = {
|
||||||
|
getBoundingClientRect() {
|
||||||
|
const selection = window.getSelection();
|
||||||
|
// there's a selection and at least one range
|
||||||
|
if (selection !== null && selection.rangeCount !== 0) {
|
||||||
|
// grab the first range, the one the user is actually on right now
|
||||||
|
// clone it so we don't actually modify the user's selection/caret position
|
||||||
|
const range = selection.getRangeAt(0).cloneRange();
|
||||||
|
|
||||||
|
// if for any reason the range is a selection (not just a caret)
|
||||||
|
// collapse it to just a caret, so we can walk it back to the :word
|
||||||
|
range.collapse(true);
|
||||||
|
|
||||||
|
// if we can, position the popper at the beginning of the emoji text (:word)
|
||||||
|
const endContainerTextContent = range.endContainer.textContent;
|
||||||
|
const startOfEmojiText = endContainerTextContent?.lastIndexOf(':');
|
||||||
|
if (
|
||||||
|
endContainerTextContent &&
|
||||||
|
isNumber(startOfEmojiText) &&
|
||||||
|
startOfEmojiText !== -1
|
||||||
|
) {
|
||||||
|
range.setStart(
|
||||||
|
range.endContainer,
|
||||||
|
range.endOffset -
|
||||||
|
(endContainerTextContent.length - startOfEmojiText)
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
log.warn(
|
||||||
|
`Could not find the beginning of the emoji word to be completed. startOfEmojiText=${startOfEmojiText}, endContainerTextContent.length=${endContainerTextContent?.length}, range.offsets=${range.startOffset}-${range.endOffset}`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return range.getClientRects()[0];
|
||||||
|
}
|
||||||
|
log.warn('No selection range when auto-completing emoji');
|
||||||
|
return new DOMRect(); // don't crash just because we couldn't get a rectangle
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
const element = createPortal(
|
const element = createPortal(
|
||||||
<Popper placement="top-start" modifiers={[sameWidthModifier]}>
|
<Popper placement="top-start" referenceElement={reference}>
|
||||||
{({ ref, style }) => (
|
{({ ref, style }) => (
|
||||||
<div
|
<div
|
||||||
ref={ref}
|
ref={ref}
|
||||||
|
@ -312,7 +352,7 @@ export class EmojiCompletion {
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</Popper>,
|
</Popper>,
|
||||||
this.root
|
document.body
|
||||||
);
|
);
|
||||||
|
|
||||||
this.options.setEmojiPickerElement(element);
|
this.options.setEmojiPickerElement(element);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue