Emoji extension
Who loves emojis? Everyone loves emojis! This package provides support for rendering emoji, either their unicode character, or with SVG/PNGs. It utilizes Emojibase for accurate and up-to-date data.
<Interweave
content="This will convert emoji unicode characters (🌀), shortcodes (:cyclone:), and emoticons to SVGs! :)"
matchers={[
new EmojiMatcher('emoji', {
convertEmoticon: true,
convertShortcode: true,
}),
]}
emojiPath={getSvgPathForEmoji}
/>
Requirements
Installation
- Yarn
- NPM
yarn add interweave interweave-emoji emojibase
npm install interweave interweave-emoji emojibase
Matching emojis
The EmojiMatcher
makes use of complex regex patterns provided by Emojibase to find and replace
emoji unicode sequences with SVG/PNGS.
import { Interweave } from 'interweave';
import { EmojiMatcher } from 'interweave-emoji';
<Interweave content="Emoji unicode character: 🌀" matchers={[new EmojiMatcher('emoji')]} />
Props
The following props are available for <Emoji />
components, all of which should be passed to an
<Interweave />
instance.
emojiSize
(string | number
) - The width and height of emojis. Defaults to1em
.emojiLargeSize
(string | number
) - The width and height of enlarged emojis. Defaults to3em
.emojiPath
(string | func
) - A path to the PNG or SVG file.enlargeEmoji
(boolean
) - Whether to enlarge the emoji or not. Automatically triggers via the matcher but can be forced with this prop. Defaults tofalse
.renderUnicode
(boolean
) - Render the unicode character instead of an image. Defaults tofalse
.
Result
Both unicode literal characters and escape sequences are supported when matching. If a match is
found, an <Emoji />
component will be rendered and passed some of the following props.
emoticon
(string
) - If applicable, an emoticon for the specific emoji character.hexcode
(string
) - The hexcode for the specific emoji character.shortcode
(string
) - The shortcode for the specific emoji character.unicode
(string
) - The unicode literal character.
Loading emoji data
Before emoji can be rendered, emoji data must be loaded from a CDN. To do this, the useEmojiData()
hook can be used, which will fetch emoji data from Emojibase's CDN. The hook returns a tuple, with
the first item being an array of all emoji data, the second item being the source object (locale,
version, etc), and the third being the data manager instance.
import BaseInterweave, { InterweaveProps } from 'interweave';
import { useEmojiData } from 'interweave-emoji';
export default function Interweave(props: InterweaveProps) {
const [emojis, source, manager] = useEmojiData({ compact: false, shortcodes: ['emojibase'] });
return <BaseInterweave {...props} emojiSource={source} />;
}
The hook supports the following optional options.
compact
(boolean
) - Whether to load the compact or full dataset. Defaults tofalse
.locale
(Locale
) - The localized data to fetch. Defaults toen
. View supported locales.shortcodes
(string[]
) - List of shortcode presets to load and join with emojis. Defaults toemojibase
. View supported presets.throwErrors
(boolean
) - Throw an error when the fetch fails. Defaults totrue
.version
(string
) - Theemojibase-data
release version to fetch. Defaults tolatest
. Read more.
Converting emoticons
Emoticons have been around longer than emoji, but emoji are much nicer to look at. Some emoji, not
all, have an associated emoticon that can be converted to an emoji character. For example, :)
would convert to 🙂.
To enable conversion of an emoticon to a unicode literal character, pass the convertEmoticon
option to the matcher.
<Interweave
content="Smiley faces :) ;p :>]"
matchers={[new EmojiMatcher('emoji', { convertEmoticon: true })]}
/>
A list of supported emoticons can be found in Emojibase.
Converting shortcodes
Shortcodes provide an easy non-unicode alternative for supporting emoji, and are represented by a
word (or two) surrounded by two colons: :boy:
.
To enable conversion of a shortcode to a unicode literal character, pass the convertShortcode
option to the matcher constructor.
<Interweave
content="Emoji shortcode: :cyclone:"
matchers={[new EmojiMatcher('emoji', { convertShortcode: true })]}
/>
A list of supported shortcodes can be found in Emojibase.
Displaying SVGs or PNGs
To begin, we must enable conversion of unicode characters to media (images, vector, etc), by
enabling the convertUnicode
option. Secondly, if you want to support shortcodes or emoticons,
enable convertShortcode
or convertEmoticon
respectively.
new EmojiMatcher('emoji', {
convertEmoticon: true,
convertShortcode: true,
convertUnicode: true,
});
Now we need to provide an absolute path to the SVG/PNG file using the emojiPath
prop. This path
must contain a {{hexcode}}
token, which will be replaced by the hexadecimal codepoint (hexcode) of
the emoji.
Or a function can be passed, which receives the hexcode as the 1st argument, and an object with
enlarged
, smallSize
, largeSize
, and size
(either depending on enlarge state) properties.
<Interweave
emojiPath="https://example.com/images/emoji/{{hexcode}}.png"
matchers={[new EmojiMatcher('emoji')]}
/>
// OR
<Interweave
emojiPath={(hexcode, { size }) => `https://example.com/images/emoji/${size}/${hexcode}.png`}
matchers={[new EmojiMatcher('emoji')]}
/>
Both media formats make use of the img
tag and will require an individual file, as sprites and
icon fonts are not supported. The following resources can be used for downloading SVG/PNG icons.
Note: SVGs require CORS to work correctly, so files will need to be stored locally, or within a CDN under the same domain. Linking to remote SVGs will not work -- use PNGs instead.
Lastly, to control the width and height of the img
, use the emojiSize
prop, which accepts a
number or string. If a number is provided, it'll be passed down to React, which defaults to px
.
<Interweave emojiSize={32} emojiLargeSize={96} /> // 32px, 96px
<Interweave emojiSize="1em" emojiLargeSize="3em" /> // 1em, 3em
I suggest using
em
scaling as the emoji will scale relative to the text around it.
Displaying unicode characters
To display native unicode characters as is, pass the renderUnicode
option to the matcher
constructor. This option will override the rendering of SVGs or PNGs, and works quite well alongside
shortcode or emoticon conversion.
new EmojiMatcher('emoji', { renderUnicode: true });
Automatic enlargement
When an emoji is the only character within the content, it will automatically be enlarged. To
disable this functionality, set enlargeThreshold
to 0. Inversely, if you want to increase the
threshold in which emojis are enlarged, increase the count.
new EmojiMatcher('emoji', { enlargeThreshold: 3 });
For example, if enlargeThreshold
is set to 3, and 3 emojis are found, all will be enlarged.
Testing utilities
Since emoji data must be fetched, this can be rather tedious to mock correctly and efficiently when
testing. To get around this, the mockEmojiData()
function can be used, which should be called
during your testing framework's boostrap and not in a beforeEach
event.
By default this will only mock English (en
) data. If you need to support additional locales, call
the method again with the locale code, but do note that the actual data will still be in English (it
just avoids a fetch).
import { mockEmojiData } from 'interweave-emoji/test';
mockEmojiData();
mockEmojiData('fr'); // For other locales
Mocking requires the
emojibase-test-utils
dependency to be installed.