{"version":3,"file":"mentions.mjs","sources":["../../../src/slate/plugins/mentions.ts"],"sourcesContent":["import type { Node as SlateNode } from \"slate\";\nimport {\n  Editor as SlateEditor,\n  Element as SlateElement,\n  Range as SlateRange,\n  Transforms as SlateTransforms,\n} from \"slate\";\n\nimport type { ComposerBodyMention } from \"../../types\";\nimport { getCharacterAfter, getCharacterBefore } from \"../utils/get-character\";\nimport { getMatchRange } from \"../utils/get-match-range\";\nimport { isEmptyString } from \"../utils/is-empty-string\";\nimport { isSelectionCollapsed } from \"../utils/is-selection-collapsed\";\n\nexport const MENTION_CHARACTER = \"@\";\n\nexport type MentionDraft = {\n  range: SlateRange;\n  text: string;\n};\n\nexport function getMentionDraftAtSelection(\n  editor: SlateEditor\n): MentionDraft | undefined {\n  const { selection } = editor;\n\n  if (!isSelectionCollapsed(selection)) {\n    return;\n  }\n\n  // Match the word at the current selection by walking back\n  // until a whitespace character is found\n  const match = getMatchRange(editor, selection);\n\n  if (!match) {\n    return;\n  }\n\n  const matchText = SlateEditor.string(editor, match);\n\n  // Check if the match starts with the mention character\n  if (!matchText.startsWith(MENTION_CHARACTER)) {\n    return;\n  }\n\n  return {\n    range: match,\n    // Exclude the mention character from the text\n    text: matchText.substring(1),\n  };\n}\n\nexport function isComposerBodyMention(\n  node: SlateNode\n): node is ComposerBodyMention {\n  return SlateElement.isElement(node) && node.type === \"mention\";\n}\n\nexport function insertMention(editor: SlateEditor, userId: string) {\n  const mention: ComposerBodyMention = {\n    type: \"mention\",\n    id: userId,\n    children: [{ text: \"\" }],\n  };\n\n  // Insert the mention\n  SlateTransforms.insertNodes(editor, mention);\n  SlateTransforms.move(editor);\n\n  const afterCharacter = editor.selection\n    ? getCharacterAfter(editor, editor.selection)\n    : undefined;\n\n  if (!afterCharacter || afterCharacter.void) {\n    // Insert a following space if needed\n    SlateTransforms.insertText(editor, \" \");\n  } else if (isEmptyString(afterCharacter.text)) {\n    // Move the selection if it's already followed by a space\n    SlateTransforms.move(editor);\n  }\n}\n\nexport function insertMentionCharacter(editor: SlateEditor) {\n  if (!editor.selection) {\n    return;\n  }\n\n  // Check if the selection is preceded or followed by a non-whitespace character\n  const beforeCharacter = getCharacterBefore(editor, editor.selection, {\n    filterVoids: true,\n  });\n  const afterCharacter = getCharacterAfter(editor, editor.selection, {\n    filterVoids: true,\n  });\n  const shouldInsertSpaceBefore =\n    beforeCharacter && !isEmptyString(beforeCharacter.text);\n  const shouldInsertSpaceAfter =\n    afterCharacter && !isEmptyString(afterCharacter.text);\n\n  if (isSelectionCollapsed(editor.selection)) {\n    const text =\n      (shouldInsertSpaceBefore ? \" \" : \"\") +\n      MENTION_CHARACTER +\n      (shouldInsertSpaceAfter ? \" \" : \"\");\n\n    // If the selection is collapsed, insert the mention character at the current selection\n    editor.insertText(text);\n\n    // If a following space was inserted, move the selection back by one\n    if (shouldInsertSpaceAfter) {\n      SlateTransforms.move(editor, {\n        distance: 1,\n        unit: \"character\",\n        reverse: true,\n      });\n    }\n  } else {\n    const beforeText = (shouldInsertSpaceBefore ? \" \" : \"\") + MENTION_CHARACTER;\n\n    // If the selection is not collapsed, insert the mention character before the selection\n    editor.insertText(beforeText, { at: SlateRange.start(editor.selection) });\n\n    if (shouldInsertSpaceAfter) {\n      editor.insertText(\" \", { at: SlateRange.end(editor.selection) });\n    }\n\n    // Collapse the selection at its end\n    SlateTransforms.collapse(editor, { edge: \"end\" });\n  }\n}\n\nexport function withMentions<T extends SlateEditor>(editor: T): T {\n  const { isInline, isVoid, markableVoid, deleteBackward } = editor;\n\n  editor.isInline = (element) => {\n    return isComposerBodyMention(element) || isInline(element);\n  };\n\n  editor.isVoid = (element) => {\n    return isComposerBodyMention(element) || isVoid(element);\n  };\n\n  editor.markableVoid = (element) => {\n    return isComposerBodyMention(element) || markableVoid(element);\n  };\n\n  editor.deleteBackward = (unit) => {\n    const { selection } = editor;\n\n    if (isSelectionCollapsed(selection)) {\n      const [mention] = SlateEditor.nodes(editor, {\n        at:\n          unit === \"character\"\n            ? SlateEditor.before(editor, selection, { unit: \"character\" })\n            : selection,\n        match: isComposerBodyMention,\n      });\n\n      deleteBackward(unit);\n\n      if (mention) {\n        SlateTransforms.insertText(editor, MENTION_CHARACTER);\n      }\n    } else {\n      deleteBackward(unit);\n    }\n  };\n\n  return editor;\n}\n"],"names":["SlateEditor","SlateElement","SlateTransforms","SlateRange"],"mappings":"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"}