Emoji Plugin

PreviousNext

A plugin for the emoji.

Docs
shadcn-editorui

Preview

Loading previewโ€ฆ
registry/new-york-v4/editor/plugins/emojis-plugin.tsx
"use client"

/**
 * 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 { JSX, useEffect } from "react"
import { useLexicalComposerContext } from "@lexical/react/LexicalComposerContext"
import type { LexicalEditor } from "lexical"
import { TextNode } from "lexical"
import { createPortal } from "react-dom"

import {
  $createEmojiNode,
  EmojiNode,
} from "@/registry/new-york-v4/editor/nodes/emoji-node"

const emojis: Map<string, [string, string]> = new Map([
  [":)", ["emoji happysmile", "๐Ÿ™‚"]],
  [":D", ["emoji veryhappysmile", "๐Ÿ˜€"]],
  [":(", ["emoji unhappysmile", "๐Ÿ™"]],
  ["<3", ["emoji heart", "โค"]],
])

function $findAndTransformEmoji(node: TextNode): null | TextNode {
  const text = node.getTextContent()

  for (let i = 0; i < text.length; i++) {
    const emojiData = emojis.get(text[i]) || emojis.get(text.slice(i, i + 2))

    if (emojiData !== undefined) {
      const [emojiStyle, emojiText] = emojiData
      let targetNode

      if (i === 0) {
        ;[targetNode] = node.splitText(i + 2)
      } else {
        ;[, targetNode] = node.splitText(i, i + 2)
      }

      const emojiNode = $createEmojiNode(emojiStyle, emojiText)
      targetNode.replace(emojiNode)
      return emojiNode
    }
  }

  return null
}

function $textNodeTransform(node: TextNode): void {
  let targetNode: TextNode | null = node

  while (targetNode !== null) {
    if (!targetNode.isSimpleText()) {
      return
    }

    targetNode = $findAndTransformEmoji(targetNode)
  }
}

function useEmojis(editor: LexicalEditor): void {
  useEffect(() => {
    if (!editor.hasNodes([EmojiNode])) {
      throw new Error("EmojisPlugin: EmojiNode not registered on editor")
    }

    return editor.registerNodeTransform(TextNode, $textNodeTransform)
  }, [editor])
}

export function EmojisPlugin(): JSX.Element | null {
  const [editor] = useLexicalComposerContext()
  useEmojis(editor)
  return null
}

Installation

npx shadcn@latest add @shadcn-editor/emoji-plugin

Usage

import { EmojiPlugin } from "@/components/ui/emoji-plugin"
<EmojiPlugin />