Back to Plate

Emoji

content/docs/(plugins)/(functionality)/(combobox)/emoji.mdx

53.0.86.7 KB
Original Source

Emoji adds two insertion paths: a : trigger that opens an inline combobox, and a toolbar popover for browsing categories. The package owns emoji data, trigger behavior, index search, picker state, frequent emoji storage, and insertion. The registry owns the inline input element and toolbar picker UI.

<ComponentPreview name="emoji-demo" /> <PackageInfo>

Features

  • : trigger powered by @platejs/combobox.
  • Edit-only inline void emoji_input node.
  • Emoji search from @emoji-mart/data.
  • Default insertion as Unicode text.
  • Custom inserted node support through createEmojiNode.
  • Toolbar popover with categories, search, preview, and frequent emoji tracking.
  • Markdown shortcode deserialization to Unicode text.
</PackageInfo>

Fast Path

<Steps>

Add The Kit

EmojiKit installs EmojiPlugin with @emoji-mart/data and renders EmojiInputPlugin with the registry inline combobox.

<ComponentSource name="emoji-kit" />
tsx
import { createPlateEditor } from 'platejs/react';

import { EmojiKit } from '@/components/editor/plugins/emoji-kit';

export const editor = createPlateEditor({
  plugins: EmojiKit,
});

Render The Inline Input

emoji-node debounces the search text, queries EmojiInlineIndexSearch, and inserts the selected emoji.

<ComponentSource name="emoji-node" />

Add Toolbar Picking

emoji-toolbar-button renders the Radix popover picker backed by useEmojiDropdownMenuState.

<ComponentSource name="emoji-toolbar-button" /> </Steps>

Ownership

LayerOwnerWhat It Does
@platejs/emojiPackageExports BaseEmojiPlugin, BaseEmojiInputPlugin, insertEmoji, emoji search libraries, settings, categories, and types.
@platejs/emoji/reactPackageExports EmojiPlugin, EmojiInputPlugin, picker hooks, and frequent emoji storage.
@platejs/comboboxPackageProvides trigger detection and transient input cleanup for the : flow.
@emoji-mart/dataDependencyProvides the emoji dataset used by the registry kit.
emoji-kitRegistryAdds EmojiPlugin with emoji-mart data and EmojiInputPlugin.withComponent(EmojiInputElement).
emoji-nodeRegistry UIRenders inline emoji search with InlineCombobox.
emoji-toolbar-buttonRegistry UIRenders the toolbar popover, category grid, search bar, and preview.
inline-comboboxRegistry UIRenders the inline trigger input and popover primitives.
@platejs/markdownPackageDeserializes emoji shortcodes such as :fire: to Unicode text.

The emoji plugin is edit-only. It inserts text or your custom node, then the transient emoji_input disappears.

Manual Setup

<Steps>

Install Packages

bash
npm install @platejs/emoji @emoji-mart/data

Add Plugins

Use @emoji-mart/data when you want the full emoji dataset instead of the package default library.

tsx
import emojiMartData from '@emoji-mart/data';
import { EmojiInputPlugin, EmojiPlugin } from '@platejs/emoji/react';
import { createPlateEditor } from 'platejs/react';

import { EmojiInputElement } from '@/components/ui/emoji-node';

export const editor = createPlateEditor({
  plugins: [
    EmojiPlugin.configure({
      options: {
        data: emojiMartData as any,
      },
    }),
    EmojiInputPlugin.withComponent(EmojiInputElement),
  ],
});

Add A Toolbar Button

Render EmojiToolbarButton in your toolbar when users should browse emoji without typing :.

tsx
import { EmojiToolbarButton } from '@/components/ui/emoji-toolbar-button';

export function FixedToolbarButtons() {
  return <EmojiToolbarButton />;
}
</Steps>

Inline Flow

The inline path is a combobox flow.

StepSource
Type :BaseEmojiPlugin trigger.
Previous character must match /^\s?$/Start of block or whitespace by default.
Insert transient inputcreateComboboxInput creates { type: KEYS.emojiInput, children: [{ text: '' }] }.
Search emoji dataEmojiInputElement calls EmojiInlineIndexSearch.getInstance(data).search(query).get().
Select a resultInlineComboboxItem removes the input and calls insertEmoji(editor, emoji).
Insert final contentinsertEmoji calls createEmojiNode(emoji) and inserts that node.

EmojiInputElement sets filter={false} because emoji search already returns filtered results. It also uses hideWhenNoValue, so the popover stays closed until the user types a search value after :.

Inserted Value

By default, selecting an emoji inserts the first native skin as text.

tsx
EmojiPlugin.configure({
  options: {
    createEmojiNode: ({ skins }) => ({ text: skins[0].native }),
  },
});

Use createEmojiNode when your app stores emoji as structured inline nodes instead of text.

tsx
EmojiPlugin.configure({
  options: {
    createEmojiNode: (emoji) => ({
      children: [{ text: emoji.id }],
      emojiId: emoji.id,
      type: 'emoji-chip',
    }),
  },
});

Toolbar Picker

EmojiToolbarButton calls useEmojiDropdownMenuState, then passes the picker state into EmojiPicker.

OptionDefaultUse
closeOnSelecttrueClose the toolbar popover after insertion.
settingsEmojiSettingsConfigure categories, per-line count, button size, and frequent emoji behavior.
settings.showFrequent.limitPackage settingLimits the frequent emoji category.

Frequent emoji counts are stored in window.localStorage through FrequentEmojiStorage. On the server, the storage class returns the default frequent set.

Markdown

@platejs/markdown deserializes emoji shortcodes to Unicode text.

md
Launch :fire: soon

Serializing the resulting value writes the Unicode emoji:

md
Launch 🔥 soon

API Reference

APIPackageUse
BaseEmojiPlugin@platejs/emojiEdit-only trigger plugin with default :, emoji data, input creation, and text insertion.
BaseEmojiInputPlugin@platejs/emojiEdit-only inline void emoji_input plugin.
EmojiPlugin@platejs/emoji/reactReact emoji plugin with nested EmojiInputPlugin.
EmojiInputPlugin@platejs/emoji/reactReact input plugin for EmojiInputElement.
insertEmoji(editor, emoji)@platejs/emojiInserts createEmojiNode(emoji).
EmojiInlineIndexSearch@platejs/emojiInline search index used by emoji-node.
useEmojiDropdownMenuState(options?)@platejs/emoji/reactBuilds toolbar popover state and picker state.
useEmojiPicker(options)@platejs/emoji/reactHandles search, category focus, preview, selection, and frequent emoji updates.
FrequentEmojiStorage@platejs/emoji/reactReads and writes frequent emoji counts through localStorage.