Я хочу реализовать что-то вроде редактора тегов. Тем не менее, это означало только для этих тегов, поэтому я хочу, чтобы пользователь видел всплывающие подсказки автозаполнения, не набирая что-то вроде @или #, как раз сам текст.
У меня есть что-то подобное, но всплывающее окно отображается в странных положениях на экране:
- когда я сначала что-то печатаю и появляется всплывающее окно, оно появляется где-то рядом с верхним левым углом экрана
- после создания первого объекта, когда нажимают SPACE и начинают печатать снова, всплывающее окно появляется на пару пикселей справа от него интуитивно понятным положением (то есть под первой буквой слова)
Вот пример известного редактора такого рода (хотя он не реализован в проекте), поэтому вы можете лучше понять, что я хочу реализовать.
Прежде всего, это функция, которая запускает всплывающие подсказки:
private onChange(editorState: EditorState) {
const content = editorState.getCurrentContent();
const selection = editorState.getSelection();
const currentBlock = content.getBlockForKey(selection.getAnchorKey());
if (selection.isCollapsed()) {
const blockText = currentBlock.getText();
const wordMeta = getWordAt(blockText, selection.getAnchorOffset());
const categoryRegex = /([\w]*)/;
const matches = wordMeta.word.match(categoryRegex);
const existingEntity = currentBlock.getEntityAt(wordMeta.begin);
if (!existingEntity && matches) {
const categorySearch = matches[1];
const selection = window.getSelection();
if (this.state.autoComplete.search !== categorySearch && selection.rangeCount > 0) {
const range = selection.getRangeAt(0);
const boundingRect = getRangeBoundingClientRect(range);
this.setState((prevState: StateType) => {
let state = {
autoComplete: {
active: true,
search: categorySearch,
searchMeta: {
begin: wordMeta.begin,
end: wordMeta.end,
},
},
selectionRect: prevState.selectionRect,
};
if (prevState.autoComplete.active === false) {
state.selectionRect = boundingRect;
}
return state;
});
}
}
}
this.props.onChange(editorState);
}
Вот функция getWordAt
:
function getWordAt(text: string, pos: number): WordMeta
{
const left = text.slice(0, pos + 1).search(/\S+$/);
const right = text.slice(pos).search(/\s/);
if (right < 0) {
return {
word: text.slice(left),
begin: left,
end: text.length,
};
}
return {
word: text.slice(left, right + pos),
begin: left,
end: right + pos,
};
}
Что было бы лучшим способом обработки позиции всплывающего окна, а может быть, и стратегии для автозавершения такого рода? Спасибо!