GitHub - Nolanlawson - Emoji-Picker-Element - A Lightweight Emoji Picker For The Modern Web
GitHub - Nolanlawson - Emoji-Picker-Element - A Lightweight Emoji Picker For The Modern Web
GitHub - Nolanlawson - Emoji-Picker-Element - A Lightweight Emoji Picker For The Modern Web
nolanlawson.github.io/emoji-picker-element/
Apache-2.0 license
Star Notifications
master Go to file
View code
README.md
emoji-picker-element
<emoji-picker></emoji-picker>
https://github.com/nolanlawson/emoji-picker-element 1/25
21/03/2023, 10:54 GitHub - nolanlawson/emoji-picker-element: A lightweight emoji picker for the modern web
Features:
Table of contents:
emoji-picker-element
Usage
Examples
Emoji support
Custom emoji font
Polyfilling flag emoji on Windows
Styling
Size
Dark mode
CSS variables
Focus outline
Small screen sizes
Custom styling
JavaScript API
Picker
Events
emoji-click
skin-tone-change
Internationalization
Built-in translations
Custom category order
Database
Constructors
constructor
Accessors
customEmoji
Methods
close
https://github.com/nolanlawson/emoji-picker-element 2/25
21/03/2023, 10:54 GitHub - nolanlawson/emoji-picker-element: A lightweight emoji picker for the modern web
delete
getEmojiByGroup
getEmojiBySearchQuery
getEmojiByShortcode
getEmojiByUnicodeOrName
getPreferredSkinTone
getTopFavoriteEmoji
incrementFavoriteEmojiCount
ready
setPreferredSkinTone
Custom emoji
Tree-shaking
Within a Svelte project
Data and offline
Data source and JSON format
Shortcodes
Cache performance
emojibase-data compatibility (deprecated)
Trimming the emoji data (deprecated)
Offline-first
Environments without IndexedDB
Design decisions
IndexedDB
Native emoji
JSON loading
Browser support
Contributing
Usage
Via npm:
import 'emoji-picker-element';
Or as a <script> tag:
https://github.com/nolanlawson/emoji-picker-element 3/25
21/03/2023, 10:54 GitHub - nolanlawson/emoji-picker-element: A lightweight emoji picker for the modern web
<emoji-picker></emoji-picker>
document.querySelector('emoji-picker')
.addEventListener('emoji-click', event => console.log(event.detail));
{
"emoji": {
"annotation": "grinning face",
"group": 0,
"order": 1,
"shortcodes": [ "grinning_face", "grinning" ],
"tags": [ "face", "grin" ],
"unicode": "😀",
"version": 1,
"emoticon": ":D"
},
"skinTone": 0,
"unicode": "😀"
}
Examples
Demo (source)
Button with tooltip/popover (source)
Inserting emoji into a text input (source)
In a React app (source)
Custom emoji font (source)
Fallback for missing flag emoji on Windows (source)
Emoji support
Emoji support varies across browsers and operating systems. By default, emoji-picker-
element will hide unsupported emoji from the picker.
https://github.com/nolanlawson/emoji-picker-element 4/25
21/03/2023, 10:54 GitHub - nolanlawson/emoji-picker-element: A lightweight emoji picker for the modern web
To work around this, you can use a custom emoji font or polyfill flag emoji on Windows.
To use a custom emoji font, first set the --emoji-font-family CSS property:
emoji-picker {
--emoji-font-family: MyCustomFont;
}
Then, specify the maximum emoji version supported by the font (see Emojipedia for a list of
versions).
In HTML:
<emoji-picker emoji-version="14.0"></emoji-picker>
Or JavaScript:
Also note that support for color fonts varies across browsers and OSes, and some browsers
may have bugs or not render the font at all. Be careful to test your supported browsers
when using this approach.
As of this writing, Windows does not support country flag emoji. This is only a problem in
Chromium-based browsers, because Firefox ships with its own emoji font.
// emoji-picker-element will use "Twemoji Mozilla" and fall back to other fonts for n
polyfillCountryFlagEmojis('Twemoji Mozilla');
Note that you do not need to do this if you are using a custom emoji font.
https://github.com/nolanlawson/emoji-picker-element 5/25
21/03/2023, 10:54 GitHub - nolanlawson/emoji-picker-element: A lightweight emoji picker for the modern web
Styling
emoji-picker-element uses Shadow DOM, so its inner styling cannot be (easily) changed
with arbitrary CSS. Refer to the API below for style customization.
Size
emoji-picker-element has a default size, but you can change it to whatever you want:
emoji-picker {
width: 400px;
height: 300px;
}
For instance, to make it expand to fit whatever container you give it:
emoji-picker {
width: 100%;
height: 100%;
}
Dark mode
By default, emoji-picker-element will automatically switch to dark mode based on
prefers-color-scheme . Or you can add the class dark or light to force dark/light mode:
<emoji-picker class="dark"></emoji-picker>
<emoji-picker class="light"></emoji-picker>
CSS variables
Most colors and sizes can be styled with CSS variables. For example:
emoji-picker {
--num-columns: 6;
--emoji-size: 3rem;
--background: gray;
}
https://github.com/nolanlawson/emoji-picker-element 6/25
21/03/2023, 10:54 GitHub - nolanlawson/emoji-picker-element: A lightweight emoji picker for the modern web
Default
Variable Default Description
(dark)
Background of the
--background #fff #222
entire <emoji-picker>
--border-
#e0e0e0 #444
color
--button-
Background of an active
active- #e6e6e6 #555555
button
background
--button-
Background of a
hover- #d9d9d9 #484848
hovered button
background
Vertical/horizontal
padding on category
--category-
var(--emoji-padding) emoji, if you want it to
emoji-padding
be different from --
emoji-padding
Width/height of
--category- category emoji, if you
var(--emoji-size)
emoji-size want it to be different
from --emoji-size
"Twemoji Mozilla","Apple
Color Emoji","Segoe UI
Emoji","Segoe UI Font family for a custom
--emoji-font-
Symbol","Noto Color emoji font (as opposed
family
Emoji","EmojiOne to native emoji)
Color","Android
Emoji",sans-serif
https://github.com/nolanlawson/emoji-picker-element 7/25
21/03/2023, 10:54 GitHub - nolanlawson/emoji-picker-element: A lightweight emoji picker for the modern web
Default
Variable Default Description
(dark)
--input-
#999 #ccc
border-color
--input-
0.5rem
border-radius
--input-
1px
border-size
--input-font-
#111 #efefef
color
--input-font-
1rem
size
--input-line-
1.5
height
--input-
0.25rem
padding
--input-
placeholder- #999 #ccc
color
--outline-
#999 #fff Focus outline color
color
--outline-
2px Focus outline width
size
https://github.com/nolanlawson/emoji-picker-element 8/25
21/03/2023, 10:54 GitHub - nolanlawson/emoji-picker-element: A lightweight emoji picker for the modern web
Default
Variable Default Description
(dark)
Focus outline
For accessibility reasons, emoji-picker-element displays a prominent focus ring. If you
want to hide the focus ring for non-keyboard users (e.g. mouse and touch only), then use
the focus-visible polyfill, e.g.:
import 'focus-visible';
emoji-picker-element already ships with the proper CSS for both the :focus-visible
standard and the polyfill.
emoji-picker-element does not ship with any CSS to explicitly handle small screen sizes.
The right CSS depends on which screen sizes your app supports, and the size of the picker
within your app. Perhaps in the future container queries can solve this problem.
Custom styling
If you absolutely must go beyond the styling API above, you can do something like this:
https://github.com/nolanlawson/emoji-picker-element 9/25
21/03/2023, 10:54 GitHub - nolanlawson/emoji-picker-element: A lightweight emoji picker for the modern web
JavaScript API
Picker
Basic usage:
Func
sort
categ
customCategorySorting function - strin
(sort
alpha
by d
Array
customEmoji CustomEmoji[] -
custo
URL
the e
"https://cdn.jsdelivr.net/npm/emoji- data
dataSource string picker-element- ( dat
data@^1/en/emojibase/data.json" sourc
when
an at
Maxi
supp
emoj
as a
(e.g.
emojiVersion number - or 1
Setti
disab
defa
supp
dete
https://github.com/nolanlawson/emoji-picker-element 10/25
21/03/2023, 10:54 GitHub - nolanlawson/emoji-picker-element: A lightweight emoji picker for the modern web
i18n
i18n I18n - (see
for d
The e
use f
skin
skinToneEmoji string " 🖐️" picke
tone
when
an at
For instance:
<emoji-picker
locale="fr"
data-source="/fr-emoji.json"
skin-tone-emoji="✌"
></emoji-picker>
Note that complex properties like i18n or customEmoji are not supported as attributes,
because the DOM only supports string attributes, not complex objects.
Events
emoji-click
The emoji-click event is fired when an emoji is selected by the user. Example format:
https://github.com/nolanlawson/emoji-picker-element 11/25
21/03/2023, 10:54 GitHub - nolanlawson/emoji-picker-element: A lightweight emoji picker for the modern web
{
emoji: {
annotation: 'thumbs up',
group: 1,
order: 280,
shortcodes: ['thumbsup', '+1', 'yes'],
tags: ['+1', 'hand', 'thumb', 'up'],
unicode: '👍️',
version: 0.6,
skins: [
{ tone: 1, unicode: '👍🏻', version: 1 },
{ tone: 2, unicode: '👍🏼', version: 1 },
{ tone: 3, unicode: '👍🏽', version: 1 },
{ tone: 4, unicode: '👍🏾', version: 1 },
{ tone: 5, unicode: '👍🏿', version: 1 }
]
},
skinTone: 4,
unicode: '👍🏾'
}
And usage:
Note that unicode will represent whatever the emoji should look like with the given
skinTone . If the skinTone is 0, or if the emoji has no skin tones, then no skin tone is
applied to unicode .
skin-tone-change
This event is fired whenever the user selects a new skin tone. Example format:
{
skinTone: 5
}
And usage:
Note that skin tones are an integer from 0 (default) to 1 (light) through 5 (dark).
https://github.com/nolanlawson/emoji-picker-element 12/25
21/03/2023, 10:54 GitHub - nolanlawson/emoji-picker-element: A lightweight emoji picker for the modern web
Internationalization
The i18n parameter specifies translations for the picker interface. Here is the default
English i18n object:
{
"categories": {
"custom": "Custom",
"smileys-emotion": "Smileys and emoticons",
"people-body": "People and body",
"animals-nature": "Animals and nature",
"food-drink": "Food and drink",
"travel-places": "Travel and places",
"activities": "Activities",
"objects": "Objects",
"symbols": "Symbols",
"flags": "Flags"
},
"categoriesLabel": "Categories",
"emojiUnsupportedMessage": "Your browser does not support color emoji.",
"favoritesLabel": "Favorites",
"loadingMessage": "Loading…",
"networkErrorMessage": "Could not load emoji.",
"regionLabel": "Emoji picker",
"searchDescription": "When search results are available, press up or down to select
"searchLabel": "Search",
"searchResultsLabel": "Search results",
"skinToneDescription": "When expanded, press up or down to select and enter to choo
"skinToneLabel": "Choose a skin tone (currently {skinTone})",
"skinTones": [
"Default",
"Light",
"Medium-Light",
"Medium",
"Medium-Dark",
"Dark"
],
"skinTonesLabel": "Skin tones"
}
Note that some of these strings are only visible to users of screen readers. They are still
important for accessibility!
Built-in translations
Community-provided translations for some languages are available. You can use them like
so:
https://github.com/nolanlawson/emoji-picker-element 13/25
21/03/2023, 10:54 GitHub - nolanlawson/emoji-picker-element: A lightweight emoji picker for the modern web
// French
picker.i18n = fr;
// German
picker.i18n = de;
Note that translations for the interface ( i18n ) are not the same as translations for the
emoji data ( dataSource and locale ). To support both, you should do something like:
If a built-in translation for your target language is not available, you can also write your own
translation and pass it in as i18n . Please feel free to contribute your translation here.
By default, custom categories are sorted alphabetically. To change this, pass in your own
customCategorySorting :
Custom emoji with no category will pass in undefined . By default, these are shown first,
with the label "Custom" (determined by i18n.categories.custom ).
Database
You can work with the database API separately, which allows you to query emoji the same
way that the picker does:
https://github.com/nolanlawson/emoji-picker-element 14/25
21/03/2023, 10:54 GitHub - nolanlawson/emoji-picker-element: A lightweight emoji picker for the modern web
Note that under the hood, IndexedDB data is partitioned based on the locale . So if you
create two Database s with two different locale s, it will store twice as much data.
Also note that, unlike the picker, the database does not filter emoji based on whether they
are supported by the current browser/OS or not. To detect emoji support, you can use a
library like is-emoji-supported.
Full API:
Constructors
constructor
Note that multiple Databases pointing to the same locale will share the same underlying
IndexedDB connection and database.
Parameters:
Array of
customEmoji CustomEmoji[] [] custom
emoji
URL to
"https://cdn.jsdelivr.net/npm/emoji-
fetch the
dataSource string picker-element-
emoji data
data@^1/en/emojibase/data.json"
from
Locale
locale string "en"
string
Returns: Database
Accessors
customEmoji
https://github.com/nolanlawson/emoji-picker-element 15/25
21/03/2023, 10:54 GitHub - nolanlawson/emoji-picker-element: A lightweight emoji picker for the modern web
Return the custom emoji associated with this Database, or the empty array if none.
Returns: CustomEmoji[]
Set the custom emoji for this database. Throws an error if custom emoji are not in the
correct format.
Parameters:
customEmoji CustomEmoji[]
Returns: void
Methods
close
▸ close(): Promise‹void›
Closes the underlying IndexedDB connection. The Database is not usable after that (or any
other Databases with the same locale).
Note that as soon as any other non-close/delete method is called, the database will
automatically reopen.
Returns: Promise‹void›
delete
▸ delete(): Promise‹void›
Deletes the underlying IndexedDB database. The Database is not usable after that (or any
other Databases with the same locale).
Note that as soon as any other non-close/delete method is called, the database will be
recreated.
Returns: Promise‹void›
getEmojiByGroup
https://github.com/nolanlawson/emoji-picker-element 16/25
21/03/2023, 10:54 GitHub - nolanlawson/emoji-picker-element: A lightweight emoji picker for the modern web
Returns all emoji belonging to a group, ordered by order . Only returns native emoji;
custom emoji don't belong to a group.
Parameters:
Returns: Promise‹NativeEmoji[]›
getEmojiBySearchQuery
Parameters:
Returns: Promise‹Emoji[]›
getEmojiByShortcode
The colons around the shortcode should not be included when querying, e.g. use
"slight_smile", not ":slight_smile:". Uppercase versus lowercase does not matter. Empty/null
strings throw an error.
Parameters:
shortcode string
https://github.com/nolanlawson/emoji-picker-element 17/25
21/03/2023, 10:54 GitHub - nolanlawson/emoji-picker-element: A lightweight emoji picker for the modern web
getEmojiByUnicodeOrName
In the case of native emoji, the unicode string can be either the main unicode string, or the
unicode of one of the skin tone variants.
Parameters:
getPreferredSkinTone
▸ getPreferredSkinTone(): Promise‹SkinTone›
Get the user's preferred skin tone. Returns 0 if not found.
Returns: Promise‹SkinTone›
getTopFavoriteEmoji
Parameters:
Returns: Promise‹Emoji[]›
incrementFavoriteEmojiCount
https://github.com/nolanlawson/emoji-picker-element 18/25
21/03/2023, 10:54 GitHub - nolanlawson/emoji-picker-element: A lightweight emoji picker for the modern web
Parameters:
Returns: Promise‹void›
ready
▸ ready(): Promise‹void›
Resolves when the Database is ready, or throws an error if the Database could not initialize.
Note that you don't need to do this before calling other APIs – they will all wait for this
promise to resolve before doing anything.
Returns: Promise‹void›
setPreferredSkinTone
Parameters:
Returns: Promise‹void›
Custom emoji
Both the Picker and the Database support custom emoji. Unlike regular emoji, custom emoji
are kept in-memory. (It's assumed that they're small, and they might frequently change, so
there's not much point in storing them in IndexedDB.)
https://github.com/nolanlawson/emoji-picker-element 19/25
21/03/2023, 10:54 GitHub - nolanlawson/emoji-picker-element: A lightweight emoji picker for the modern web
[
{
name: 'Garfield',
shortcodes: ['garfield'],
url: 'http://example.com/garfield.png',
category: 'Cats'
},
{
name: 'Heathcliff',
shortcodes: ['heathcliff'],
url: 'http://example.com/heathcliff.png',
category: 'Cats'
},
{
name: 'Scooby-Doo',
shortcodes: ['scooby'],
url: 'http://example.com/scooby.png',
category: 'Dogs'
}
]
Note that names are assumed to be unique (case-insensitive), and it's assumed that the
shortcodes have at least one entry.
The category is optional. If you don't provide it, then the custom emoji will appear in a
single category called "Custom".
Or the Database :
picker.customEmoji = [ /* ... */ ];
database.customEmoji = [ /* ... */ ];
Tree-shaking
https://github.com/nolanlawson/emoji-picker-element 20/25
21/03/2023, 10:54 GitHub - nolanlawson/emoji-picker-element: A lightweight emoji picker for the modern web
If you want to import the Database without the Picker , or you want to code-split them
separately, then do:
The reason for this is that Picker automatically registers itself as a custom element,
following web component best practices. But this adds side effects, so bundlers like
Webpack and Rollup do not tree-shake as well, unless the modules are imported from
completely separate files.
svelte.js is the same as picker.js , except it import s Svelte rather than bundling it.
While this option can reduce your bundle size, note that it only works if your Svelte version
is compatible with emoji-picker-element 's Svelte version (v3 currently).
Shortcodes
https://github.com/nolanlawson/emoji-picker-element 21/25
21/03/2023, 10:54 GitHub - nolanlawson/emoji-picker-element: A lightweight emoji picker for the modern web
There is no standard for shortcodes, so unlike other emoji data, there is some disagreement
as to what a "shortcode" actually is.
Cache performance
For optimal cache performance, it's recommended that your server expose an ETag
header. If so, emoji-picker-element can avoid re-downloading the entire JSON file over
and over again. Instead, it will do a HEAD request and just check the ETag .
If the server hosting the JSON file is not the same as the one containing the emoji picker,
then the cross-origin server will also need to expose Access-Control-Allow-Origin: * and
Access-Control-Allow-Headers: ETag (or Access-Control-Allow-Headers: * ). jsdelivr
already does this, which is partly why it is the default.
Note that Safari does not currently support Access-Control-Allow-Headers: * , but it does
support Access-Control-Allow-Headers: ETag .
If emoji-picker-element cannot use the ETag for any reason, it will fall back to the less
performant option, doing a full GET request on every page load.
When using emojibase-data , you must use the full emojibase-data JSON file, not the
"compact" one (i.e. data.json , not compact.json ).
If you are hosting the emojibase-data JSON file yourself and would like it to be as small as
possible, then you can use the utility trimEmojiData function:
https://github.com/nolanlawson/emoji-picker-element 22/25
21/03/2023, 10:54 GitHub - nolanlawson/emoji-picker-element: A lightweight emoji picker for the modern web
Offline-first
emoji-picker-element uses a "stale while revalidate" strategy to update emoji data. In
other words, it will use any existing data it finds in IndexedDB, and lazily update via the
dataSource in case that data has changed. This means it will work offline-first the second
time it runs.
If you would like to manage the database yourself (e.g. to ensure that it's correctly
populated before displaying the Picker ), then create a new Database instance and wait
for its ready() promise to resolve:
If emoji-picker-element fails to fetch the JSON data the first time it loads, then it will
display an error message.
For browsers that don't support IndexedDB, such as Firefox in private browsing mode, you
can polyfill it using fake-indexeddb. Here is a working example and more details.
For Node.js environments such as Jest or JSDom, you can also use fake-indexeddb. A
working example can be found in the tests for this very project.
Design decisions
Some of the reasoning behind why emoji-picker-element is built the way it is.
IndexedDB
https://github.com/nolanlawson/emoji-picker-element 23/25
21/03/2023, 10:54 GitHub - nolanlawson/emoji-picker-element: A lightweight emoji picker for the modern web
The emojibase-data English JSON file is 854kB, and the "compact" version is still 543kB.
That's a lot of data to keep in memory just for an emoji picker. And it's not as if that number
is ever going down; the Unicode Consortium keeps adding more emoji every year.
1. We don't need to keep the full emoji data in memory at all times.
2. After the first load, there is no need to download, parse, and index the JSON file again,
because it's already available in IndexedDB.
3. If you want, you can even load the IndexedDB data in a web worker, keeping the main
thread free from non-UI data processing.
Native emoji
To avoid downloading a large sprite sheet or font file – which may look out-of-place on
different platforms, or may have IP issues – emoji-picker-element only renders native
emoji by default. This means it is limited to the emoji font actually installed on the user's
device.
That said, emoji-picker-element does support custom emoji fonts if you really want.
JSON loading
Browsers deal with JSON more efficiently when it's loaded via fetch() rather than
embedded in JavaScript. It's faster for the browser to parse JSON than JavaScript, becuase
the data is being parsed in the more tightly-constrained JSON format than the generic
JavaScript format.
Plus, embedding the JSON directly would mean re-parsing the entire object on second load,
which is something we want to avoid since the data is already in IndexedDB.
Browser support
emoji-picker-element only supports the latest versions of Chrome, Firefox, and Safari, as
well as equivalent browsers (Edge, Opera, etc.). If you need support for older browsers, you
will need polyfills for the following things (non-exhaustive list):
Custom elements
Shadow DOM
ES2019+
https://github.com/nolanlawson/emoji-picker-element 24/25
21/03/2023, 10:54 GitHub - nolanlawson/emoji-picker-element: A lightweight emoji picker for the modern web
That said, older browsers may not have a color emoji font installed at all, so emoji-picker-
element will not work in those cases.
Contributing
See CONTRIBUTING.md.
Releases
45 tags
Packages
No packages published
Used by 638
+ 630
Contributors 12
Languages
https://github.com/nolanlawson/emoji-picker-element 25/25