UNPKG

@churchapps/apphelper-markdown

Version:

ChurchApps markdown/lexical editor components

53 lines (52 loc) 2.59 kB
/** * 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; }