@churchapps/apphelper-markdown
Version:
ChurchApps markdown/lexical editor components
53 lines (52 loc) • 2.59 kB
JavaScript
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
import "material-symbols";
import { useLexicalComposerContext } from "@lexical/react/LexicalComposerContext";
import { $createTextNode, TextNode } from "lexical";
import { useEffect } from "react";
import materialIcons from "../../IconNamesList";
import { $createEmojiNode, EmojiNode } from "./EmojiNode";
import { EMOJI_NODE_MARKDOWN_REGEX } from "./EmojiNodeTransform";
function useEmojis(editor) {
useEffect(() => {
if (!editor.hasNodes([EmojiNode, TextNode])) {
throw new Error("EmojisPlugin: EmojiNode not registered on editor");
}
if (!materialIcons || !Array.isArray(materialIcons)) {
return;
// throw new Error('EmojisPlugin: materialIcons not properly loaded');
}
return editor.registerNodeTransform(TextNode, (textNode) => {
if (EMOJI_NODE_MARKDOWN_REGEX.test(textNode.getTextContent()) || materialIcons.map((materialIcon) => ":" + materialIcon + ":").some((materialIcon) => textNode.getTextContent().includes(materialIcon))) {
const materialIconToInsert = materialIcons.find((materialIcon) => textNode.getTextContent().replaceAll(":", "").includes(materialIcon));
if (!materialIconToInsert)
return;
const initialTextInput = textNode.getTextContent();
const emojiNode = $createEmojiNode(materialIconToInsert);
const leftoverTextNodes = [];
initialTextInput?.split(":").forEach((leftoverTextString, index) => {
if (materialIcons.includes(leftoverTextString)) {
const emojiNode = $createEmojiNode(leftoverTextString);
leftoverTextNodes.push(emojiNode);
return;
}
leftoverTextNodes.push($createTextNode(leftoverTextString));
});
textNode.setTextContent("");
textNode.getParent().splice(textNode.getIndexWithinParent(), 1, leftoverTextNodes);
(leftoverTextNodes.find((node) => materialIcons.includes(node.__text)) || leftoverTextNodes[leftoverTextNodes.length - 1]).select();
textNode.remove();
}
});
}, [editor]);
}
export default function EmojisPlugin() {
const [editor] = useLexicalComposerContext();
useEmojis(editor);
return null;
}