Skip to content

Pro pre-sale is open. Installation opens January 2027. See Pro

Components

EmojiPicker

A search field, a row of category buttons and a scrolling grid of emoji, with a preview of the emoji under the pointer or the focus. Built in: 536 common emoji in eight categories, with English names to search. It has no frame: put it in a Popover, or use it inside MessageActions.

  • npm: 1 direct, 3 total
  • registry: 3 direct, 3 total

Preview

Frequently used

Smileys

People

Animals and nature

Food and drink

Activities

Travel and places

Objects

Symbols

Props

  • columns
  • showPreview
  • frequent
import { EmojiPicker } from "@/components/ui/emoji-picker"

const pickEmoji = (emoji: string) => { /* Insert the emoji where the caret is. */ }

<EmojiPicker frequent={["👍", "❤️", "😂", "🎉", "🙏", "🔥"]} onEmojiSelect={pickEmoji} className="rounded-container border border-border p-sm" />

Usage

When to use

  • Pick an emoji to put in a message or as a reaction.
  • Let someone search a set of emoji by name.

When not to use

  • Pick from a few fixed reactions. Use the quick reactions in MessageActions.
  • Pick an icon for a project or a page. Use a grid of icon Buttons in a Popover.
  • Rate something. Use Rating.

Examples

Picker

Smileys

People

Animals and nature

Food and drink

Activities

Travel and places

Objects

Symbols

import { EmojiPicker } from "@/components/ui/emoji-picker"

const pickEmoji = (emoji: string) => { /* Insert the emoji where the caret is. */ }

<EmojiPicker onEmojiSelect={pickEmoji} className="rounded-container border border-border p-sm" />

Frequently used

Emoji the user picks most come first, in their own section.

Frequently used

Smileys

People

Animals and nature

Food and drink

Activities

Travel and places

Objects

Symbols

import { EmojiPicker } from "@/components/ui/emoji-picker"

const pickEmoji = (emoji: string) => { /* Insert the emoji where the caret is. */ }

<EmojiPicker frequent={["👍", "❤️", "😂", "🎉", "🙏", "🔥"]} onEmojiSelect={pickEmoji} className="rounded-container border border-border p-sm" />

In a popover

The usual place: a button beside a field opens it.

import { IconMoodSmile } from "@tabler/icons-react"
import { Button } from "@/components/ui/button"
import { EmojiPicker } from "@/components/ui/emoji-picker"
import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover"

const pickEmoji = (emoji: string) => { /* Insert the emoji where the caret is. */ }

<Popover>
  <PopoverTrigger asChild>
    <Button variant="secondary" iconOnly aria-label="Add emoji">
      <IconMoodSmile size={16} />
    </Button>
  </PopoverTrigger>
  <PopoverContent className="w-auto p-sm">
    <EmojiPicker autoFocus onEmojiSelect={pickEmoji} />
  </PopoverContent>
</Popover>

Do and don't

Do

  • Open it from a button in a Popover, and close the Popover when an emoji is picked.
  • Pass frequent with the user's most used emoji, kept by your app.
  • Pass categories with translated names when search should work in the page's language.

Don't

  • Do not use it to pick reactions only; MessageActions offers quick reactions first.
  • Do not shrink it below 8 columns of md buttons on touch screens.
  • Do not show emoji as images of text; keep the system emoji font.

Props

NameTypeValuesDefaultDescription
onEmojiSelect(emoji: string) => void--Called with the emoji the user picks, such as 👍.
frequentstring[]--Emoji the user picks most, shown first. Keep the list yourself, such as in local storage.
categories{ id: string; label: string; emojis: { emoji: string; name: string; keywords?: string[] }[] }[]--The categories to show. Default: the built-in set. The ids smileys, people, animals, food, activities, travel, objects and symbols pick a built-in icon.
columnsnumber-8Emoji per row.
showPreviewboolean-trueShows the emoji under the pointer or the focus, with its name, under the grid.
autoFocusboolean-falseFocuses the search field on mount, such as when the picker opens in a Popover.
labels{ picker?: string; search?: string; searchPlaceholder?: string; categories?: string; frequent?: string; results?: string; empty?: string }--Names and headings. Defaults: Emoji, Search emoji, Search, Emoji categories, Frequently used, Results, No emoji found. Vietnamese: Biểu tượng cảm xúc, Tìm biểu tượng cảm xúc, Tìm kiếm, Nhóm biểu tượng, Dùng thường xuyên, Kết quả, Không tìm thấy biểu tượng nào.

Anatomy

PartDescription
rootThe picker: search, categories, grid and preview, stacked, 288px wide.
searchAn Input in size sm with a search icon.
navThe row of category buttons, hidden while searching.
categoryA 28px icon button that scrolls its section into view, with a 44px touch target. The section in view takes the muted accent fill.
viewportThe 256px scrolling area of sections.
sectionOne category: its heading over its grid.
headingThe category name above its emoji.
itemOne emoji button, the size of an md control, at the xl text size.
emptyThe text shown when nothing matches the search.
previewThe emoji under the pointer or the focus, with its name, under a line.

Accessibility

Role: group

KeysAction
Arrow DownFrom the search field, moves into the grid.
Arrow keysIn the grid, move by one emoji or one row. Arrow Up from the first row goes back to the search field.
Home / EndIn the grid, move to the first or the last emoji.
Enter / SpacePicks the focused emoji. Enter in the search field picks the first result.
TabMoves from the search field to the category buttons, then to the grid, which is one tab stop.
  • A group named by labels.picker (EN `Emoji`, VI `Biểu tượng cảm xúc`). The search field is named by labels.search.
  • Each emoji is a button named by its name, such as EN `thumbs up`, so a screen reader never reads only the glyph.
  • Each section is a region named by its heading. The category buttons are named by their category and the one in view has aria-current.
  • The preview under the grid is drawn only; the buttons already say their names.
  • When nothing matches, the empty text is a polite status, EN `No emoji found`.
  • Built-in names are English. Pass categories with names in another language to search in it.

Install

npx werewolf-ui add emoji-picker

Run npx werewolf-ui init once in your app before adding components. Init sets up tokens, their CSS import and agent rules. Add installs this component and its dependencies while preserving your theme. See Installation for requirements and the alternative registry setup.