zent
Version:
一套前端设计语言和基于React的实现
96 lines (78 loc) • 2.34 kB
text/typescript
import { isWhiteSpace } from './utils';
import { MENTION_NOT_FOUND, MENTION_FOUND } from './constants';
import findLastIndex from '../utils/findLastIndex';
import findIndex from '../utils/findIndex';
export type FindMentionAtCaretPositionReturn =
| {
code: 1;
}
| {
code: 2;
// where to start measure caret screen position
caretMeasureStart: number;
// search keyword is at range: [searchStart, searchEnd]
searchStart: number;
searchEnd: number;
// mention placeholder is at range [placeholderStart, placeholderEnd]
placeholderStart: number;
placeholderEnd: number;
};
const NOT_FOUND: FindMentionAtCaretPositionReturn = {
code: MENTION_NOT_FOUND,
};
export function findMentionAtCaretPosition({
input,
value,
triggerText,
}): FindMentionAtCaretPositionReturn {
const { selectionEnd } = input;
// Find the first space before caret
const mentionStartIndex = findLastIndex(
value,
isWhiteSpace,
selectionEnd - 1
);
// Don't trigger suggestion if caret is right after the space
if (mentionStartIndex + 1 === selectionEnd) {
// this.setStateIfChange(this.getDefaultState());
return NOT_FOUND;
}
// Find the next space after caret
const mentionEndIndex = findIndex(value, isWhiteSpace, selectionEnd);
// Now try to match triggerText from mentionStartIndex
let i =
mentionStartIndex === -1
? 0
: Math.min(mentionStartIndex + 1, value.length - 1);
const caretMeasureStart = i;
const end =
mentionEndIndex === -1
? value.length - 1
: Math.max(mentionEndIndex - 1, 0);
let j = 0;
// const { triggerText } = this.props;
const triggerEnd = triggerText.length - 1;
let foundTrigger = true;
while (j <= triggerEnd) {
if (i > end || value[i] !== triggerText[j]) {
foundTrigger = false;
break;
}
i++;
j++;
}
if (!foundTrigger) {
return NOT_FOUND;
}
return {
code: MENTION_FOUND,
// where to start measure caret screen position
caretMeasureStart,
// search keyword is at range: [searchStart, searchEnd]
searchStart: i,
searchEnd: end,
// mention placeholder is at range [placeholderStart, placeholderEnd]
placeholderStart: caretMeasureStart + triggerText.length,
placeholderEnd: end,
};
}