UNPKG

@liveblocks/react-ui

Version:

A set of React pre-built components for the Liveblocks products. Liveblocks is the all-in-one toolkit to build collaborative products like Figma, Notion, and more.

123 lines (119 loc) 4.34 kB
'use strict'; var slate = require('slate'); var getCharacter = require('../utils/get-character.cjs'); var getMatchRange = require('../utils/get-match-range.cjs'); var isEmptyString = require('../utils/is-empty-string.cjs'); var isWhitespaceCharacter = require('../utils/is-whitespace-character.cjs'); const MENTION_CHARACTER = "@"; function getMentionDraftAtSelection(editor) { const { selection } = editor; if (!selection || !slate.Range.isCollapsed(selection)) { return; } const match = getMatchRange.getMatchRange(editor, selection, ["@"], { include: true, allowConsecutiveWhitespace: false, ignoreTerminator: (_, point) => { const characterBefore = getCharacter.getCharacterBefore(editor, point); if (characterBefore && !isWhitespaceCharacter.isWhitespaceCharacter(characterBefore.text)) { return true; } return false; } }); if (!match) { return; } const matchText = slate.Editor.string(editor, match); if (!matchText.startsWith(MENTION_CHARACTER) || matchText.length > 1 && isWhitespaceCharacter.isWhitespaceCharacter(matchText[1])) { return; } return { range: match, text: matchText.substring(1) }; } function isComposerBodyMention(node) { return slate.Element.isElement(node) && node.type === "mention"; } function insertMention(editor, userId) { const mention = { type: "mention", id: userId, children: [{ text: "" }] }; slate.Transforms.insertNodes(editor, mention); slate.Transforms.move(editor); const afterCharacter = editor.selection ? getCharacter.getCharacterAfter(editor, editor.selection) : void 0; if (!afterCharacter || afterCharacter.void) { slate.Transforms.insertText(editor, " "); } else if (isEmptyString.isEmptyString(afterCharacter.text)) { slate.Transforms.move(editor); } } function insertMentionCharacter(editor) { if (!editor.selection) { return; } const beforeCharacter = getCharacter.getCharacterBefore(editor, editor.selection, { filterVoids: true }); const afterCharacter = getCharacter.getCharacterAfter(editor, editor.selection, { filterVoids: true }); const shouldInsertSpaceBefore = beforeCharacter && !isEmptyString.isEmptyString(beforeCharacter.text); const shouldInsertSpaceAfter = afterCharacter && !isEmptyString.isEmptyString(afterCharacter.text); if (!slate.Range.isCollapsed(editor.selection)) { const text = (shouldInsertSpaceBefore ? " " : "") + MENTION_CHARACTER + (shouldInsertSpaceAfter ? " " : ""); editor.insertText(text); if (shouldInsertSpaceAfter) { slate.Transforms.move(editor, { distance: 1, unit: "character", reverse: true }); } } else { const beforeText = (shouldInsertSpaceBefore ? " " : "") + MENTION_CHARACTER; editor.insertText(beforeText, { at: slate.Range.start(editor.selection) }); if (shouldInsertSpaceAfter) { editor.insertText(" ", { at: slate.Range.end(editor.selection) }); } slate.Transforms.collapse(editor, { edge: "end" }); } } function withMentions(editor) { const { isInline, isVoid, markableVoid, deleteBackward } = editor; editor.isInline = (element) => { return isComposerBodyMention(element) || isInline(element); }; editor.isVoid = (element) => { return isComposerBodyMention(element) || isVoid(element); }; editor.markableVoid = (element) => { return isComposerBodyMention(element) || markableVoid(element); }; editor.deleteBackward = (unit) => { const { selection } = editor; if (selection && slate.Range.isCollapsed(selection)) { const [mention] = slate.Editor.nodes(editor, { at: unit === "character" ? slate.Editor.before(editor, selection, { unit: "character" }) : selection, match: isComposerBodyMention }); deleteBackward(unit); if (mention) { slate.Transforms.insertText(editor, MENTION_CHARACTER); } } else { deleteBackward(unit); } }; return editor; } exports.MENTION_CHARACTER = MENTION_CHARACTER; exports.getMentionDraftAtSelection = getMentionDraftAtSelection; exports.insertMention = insertMention; exports.insertMentionCharacter = insertMentionCharacter; exports.isComposerBodyMention = isComposerBodyMention; exports.withMentions = withMentions; //# sourceMappingURL=mentions.cjs.map