Find out what's new in Tiptap Editor 3.0

Emoji Menu

Available in Start plan

A fully accessible emoji picker menu for Tiptap editors. Browse and search through emojis with keyboard navigation support, fallback images, and customizable filtering options.

Installation

Add the component via the Tiptap CLI:

npx @tiptap/cli@latest add emoji-menu

Components

<EmojiMenu />

A comprehensive emoji picker menu with search and navigation capabilities.

Usage

import { EmojiMenu } from '@/components/tiptap-ui/emoji-menu'
import { gitHubEmojis } from '@tiptap/extension-emoji'
import type { EmojiItem } from '@tiptap/extension-emoji'

export default function MyEmojiPicker() {
  const [selectedEmoji, setSelectedEmoji] = useState<EmojiItem | null>(null)

  const handleEmojiSelect = (emoji: EmojiItem) => {
    setSelectedEmoji(emoji)
    console.log('Selected emoji:', emoji.name, emoji.emoji)
  }

  const handleClose = () => {
    console.log('Emoji menu closed')
  }

  return (
    <EmojiMenu
      emojis={gitHubEmojis}
      onSelect={handleEmojiSelect}
      onClose={handleClose}
      showSearch={true}
      selector=".my-emoji-menu"
    />
  )
}

Props

NameTypeDefaultDescription
emojisT[] extends EmojiItemundefinedArray of emoji items to display
onSelect(emoji: T) => voidundefinedCallback fired when an emoji is selected
onClose() => voidundefinedCallback fired when the menu is closed
showSearchbooleanfalseWhether to show the search input
selectorstring".emoji-menu-list"CSS selector for the scrollable menu container

<EmojiMenuItem />

Individual emoji item component used within the emoji menu.

Usage

import { EmojiMenuItem } from '@/components/tiptap-ui/emoji-menu'
import type { EmojiItem } from '@tiptap/extension-emoji'

function CustomEmojiList({ emojis, onSelect, selectedIndex }) {
  return (
    <div>
      {emojis.map((emoji, index) => (
        <EmojiMenuItem
          key={emoji.name}
          emoji={emoji}
          index={index}
          isSelected={index === selectedIndex}
          onSelect={onSelect}
          selector=".custom-emoji-list"
        />
      ))}
    </div>
  )
}

Props

NameTypeDefaultDescription
emojiT extends EmojiItemundefinedThe emoji item to render
indexnumberundefinedThe index of the emoji in the list
isSelectedbooleanundefinedWhether this emoji item is currently selected
onSelect(emoji: T) => voidundefinedCallback fired when this emoji is selected
selectorstringundefinedCSS selector for scroll container

Utilities

getFilteredEmojis(props)

Filters and sorts emoji data based on search query.

import { getFilteredEmojis } from '@/components/tiptap-ui/emoji-menu'
import { gitHubEmojis } from '@tiptap/extension-emoji'

const filteredEmojis = getFilteredEmojis({
  query: 'smile',
  emojis: gitHubEmojis,
})

console.log('Filtered emojis:', filteredEmojis.length)

Parameters

NameTypeDescription
props.querystringSearch query to filter emojis by
props.emojisT[] extends EmojiItemArray of emoji items to filter

Returns

T[] - Filtered and sorted array of emoji items (max 100 results).

searchEmojiData(query, emojiData)

Checks if an emoji matches the search query.

import { searchEmojiData } from '@/components/tiptap-ui/emoji-menu'

const emoji = {
  name: 'grinning',
  shortcodes: ['grinning', 'grinning_face'],
  tags: ['face', 'smile'],
  emoji: '😀',
}

const matches = searchEmojiData('smile', emoji) // true

Parameters

NameTypeDescription
querystringSearch query string
emojiDataT extends EmojiItemEmoji item to test against query

Returns

boolean - Whether the emoji matches the search query.

Search Functionality

The emoji menu supports intelligent search across multiple emoji properties:

Search Fields

  • Name: Primary emoji name (e.g., "grinning")
  • Shortcodes: Alternative names (e.g., "grinning_face")
  • Tags: Descriptive tags (e.g., "face", "smile")

Search Features

  • Case-insensitive: Search works regardless of capitalization
  • Partial matching: Finds emojis containing the search term
  • Multi-field search: Searches across name, shortcodes, and tags
  • Result limiting: Returns maximum 100 results for performance
  • Alphabetical sorting: Results are sorted by emoji name

Example Search Queries

// Search by name
getFilteredEmojis({ query: 'heart', emojis }) // ❤️, 💖, 💕, etc.

// Search by tag
getFilteredEmojis({ query: 'face', emojis }) // 😀, 😃, 😄, etc.

// Search by shortcode
getFilteredEmojis({ query: 'grinning', emojis }) // 😀, 😃, etc.

// Empty query returns first 100 emojis
getFilteredEmojis({ query: '', emojis }) // First 100 emojis

Keyboard Navigation

The emoji menu includes full keyboard navigation support:

  • Arrow Keys: Navigate up/down through emoji list
  • Enter: Select the currently highlighted emoji
  • Escape: Close the menu
  • Type to Search: Automatically focus search input and filter

Navigation is provided by the useMenuNavigation hook and includes:

  • Smart Scrolling: Automatically scrolls selected item into view
  • Overflow Handling: Prevents scrolling beyond menu boundaries
  • Focus Management: Maintains focus states during navigation

Custom Emoji Data

const customEmojis = [
  {
    emoji: '🎉',
    name: 'party',
    shortcodes: ['party', 'celebration'],
    tags: ['celebrate', 'fun'],
    group: 'activities',
    emoticons: [],
    version: 1,
    fallbackImage: 'https://example.com/party-emoji.png',
  },
  // ... more custom emojis
]

function CustomEmojiPicker() {
  return (
    <EmojiMenu
      emojis={customEmojis}
      onSelect={(emoji) => console.log('Custom emoji:', emoji)}
      showSearch={true}
    />
  )
}

Emoji Item Interface

The EmojiItem interface from @tiptap/extension-emoji:

interface EmojiItem {
  emoji: string // The actual emoji character: "😀"
  name: string // Primary name: "grinning"
  shortcodes: string[] // Alternative names: ["grinning", "grinning_face"]
  tags: string[] // Descriptive tags: ["face", "smile"]
  group: string // Category group: "smileys-emotion"
  emoticons: string[] // Text representations: [":D"]
  version: number // Unicode version: 1.0
  fallbackImage?: string // Optional fallback image URL
}

Requirements

Dependencies

  • @tiptap/react - Core Tiptap React integration
  • @tiptap/extension-emoji - Emoji extension and types

Optional Dependencies

  • sass - For SCSS styling support
  • sass-embedded - Enhanced Sass processing

Referenced Components

  • use-menu-navigation (hook)
  • button, button-group (primitive)
  • input (primitive)
  • card, card-body, card-header (primitive)
  • tiptap-collab-utils (lib)