Emoji Menu
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
Name | Type | Default | Description |
---|---|---|---|
emojis | T[] extends EmojiItem | undefined | Array of emoji items to display |
onSelect | (emoji: T) => void | undefined | Callback fired when an emoji is selected |
onClose | () => void | undefined | Callback fired when the menu is closed |
showSearch | boolean | false | Whether to show the search input |
selector | string | ".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
Name | Type | Default | Description |
---|---|---|---|
emoji | T extends EmojiItem | undefined | The emoji item to render |
index | number | undefined | The index of the emoji in the list |
isSelected | boolean | undefined | Whether this emoji item is currently selected |
onSelect | (emoji: T) => void | undefined | Callback fired when this emoji is selected |
selector | string | undefined | CSS 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
Name | Type | Description |
---|---|---|
props.query | string | Search query to filter emojis by |
props.emojis | T[] extends EmojiItem | Array 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
Name | Type | Description |
---|---|---|
query | string | Search query string |
emojiData | T extends EmojiItem | Emoji 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 supportsass-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)