StartFoundationsComponentsContent

Emoji picker

An emoji picker is a panel for finding and inserting an emoji. People search or browse by category, choose a skin tone, and pick; you insert the emoji.

Stable Figma
OverviewUsageAPIAccessibility
<tk-emoji-picker></tk-emoji-picker>

Anatomy

Part What it is
tk-emoji-picker the panel; raised, with rounded corners
search part the search box, with the skin-tone button at its end
nav part a row of category tabs
grid part the scrolling emoji grid, or the results while searching
preview part optional footer with the focused emoji and its name

Recently used emoji come first, then the categories: Smileys & emotion, People & body, Animals & nature, Food & drink, Travel & places, Activities, Objects, Symbols, Flags. The grid fades at an edge while there is more to scroll.

Options

<tk-emoji-picker preview columns="6" label="Choose a reaction"></tk-emoji-picker>
  • preview: shows the focused or hovered emoji large, with its name.
  • columns: the number of emoji per row, 8 by default.
  • label: names the grid, "Choose an emoji" by default.
  • flags: the Flags category, on by default. Flags don't show on Windows; to drop them, set picker.flags = false in script. The attribute can't turn it off.

Search and browse

  • Typing filters to matching emoji. With no match, the picker says "No emoji found. Try another word." Esc or an empty box returns to browsing.
  • A category tab scrolls to that category; the tabs follow as people scroll.
  • The search box doesn't change on hover. On focus, its border takes the focus color and grows thicker inward.

Skin tone

The button at the end of the search box opens six tones, Default to Dark. The tone applies to every emoji that has variants. It is the skin-tone attribute, from 0 to 5; a change by the user fires tk-skin-tone-change.

Inserting and recents

Listen for tk-emoji-select and insert detail.emoji, which already has the skin tone applied. The picker doesn't insert anything itself.

<tk-emoji-picker id="picker"></tk-emoji-picker>
<script type="module">
  const picker = document.getElementById('picker');
  picker.addEventListener('tk-emoji-select', (event) => {
    document.getElementById('message').value += event.detail.emoji;
  });
</script>

For the recently used row, either set persist-recents and the picker keeps the list and the tone in local storage, or keep the list yourself and set recent:

<tk-emoji-picker id="reactions"></tk-emoji-picker>
<script type="module">
  const picker = document.getElementById('reactions');
  let recent = JSON.parse(localStorage.getItem('recent') ?? '[]');
  picker.recent = recent;
  picker.addEventListener('tk-emoji-select', (event) => {
    recent = [event.detail.emoji, ...recent.filter((e) => e !== event.detail.emoji)].slice(0, 24);
    localStorage.setItem('recent', JSON.stringify(recent));
    picker.recent = recent;
  });
</script>

With neither, the row says "No recent emoji yet".

In a popover

To open the picker from a button, put it in a Popover and remove the popover's padding:

<tk-popover label="Emoji" style="--tk-popover-padding: 0;">
  <tk-icon-button slot="trigger" label="Add emoji"><span aria-hidden="true">😀</span></tk-icon-button>
  <tk-emoji-picker></tk-emoji-picker>
</tk-popover>

tk-emoji-select reaches your listener outside the popover. Open it on click, never on hover.

Native emoji

Emoji are drawn by the system's emoji font, so they look like the rest of the person's device and need no images.

  • Flags show as two letters on Windows.
  • Combined emoji, such as 👨‍👩‍👧, may show as separate emoji on older systems, and very new emoji as an empty box.
  • No color token tints emoji.
  • The emoji data loads the first time a picker appears, about 85 kB gzipped, and is shared by every picker on the page. The grid says "Loading emoji…" until it arrives.