Emoji

Consistent Emoji display across all platforms, independent of the host system.

Attribution to JoyPixels

The beautiful Emoji art used in this plugin is provided by the Joy Pixels project. Personal or non-commercial use of the emojis do not require attribution. For the rights to use our emojis still for free in commercial projects proper attribution in form of a link is required. More here: https://www.joypixels.com/licensing.

Implementation

Emoji unicode characters are wrapped in a span, hidden, and displayed instead through a background image. This creates consistency across all platforms while maintaining natural copy/pasting functionality.

If useNativeArt parameter is used, emoji unicode characters are displayed. This enables displaying platform specific art for emojis.

Usage

To use simply type : which will show an autocomplete with matching emojis.

Supported Environment

  • Desktop: Yes
  • Mobile: Yes
  • Screen-reader: Yes

Getting Started

npm install @draft-js-plugins/editor
npm install @draft-js-plugins/emoji
gettingStarted.js
// It is important to import the Editor which accepts plugins.
import Editor from '@draft-js-plugins/editor';
import createEmojiPlugin from '@draft-js-plugins/emoji';
import React from 'react';

// Creates an Instance. At this step, a configuration object can be passed in
// as an argument.
const emojiPlugin = createEmojiPlugin();
const { EmojiSuggestions, EmojiSelect } = emojiPlugin;

// The Editor accepts an array of plugins. In this case, only the emojiPlugin is
// passed in, although it is possible to pass in multiple plugins.
// The EmojiSuggestions component is internally connected to the editor and will
// be updated & positioned once the user starts the autocompletion with a colon.
// The EmojiSelect component also is internally connected to the editor. He add
// a button which allows open emoji select popup.
const MyEditor = ({ editorState, onChange }) => (
  <div>
    <Editor
      editorState={editorState}
      onChange={onChange}
      plugins={[emojiPlugin]}
    />
    <EmojiSuggestions />
    <EmojiSelect />
  </div>
);

export default MyEditor;

Importing the default styles

The plugin ships with a default styling available at this location in the installed package:  node_modules/@draft-js-plugins/emoji/lib/plugin.css

Webpack Usage

  • 1. Install Webpack loaders:  npm i style-loader css-loader --save-dev
  • 2. Add the below section to Webpack config (if your config already has a loaders array, simply add the below loader object to your existing list.
    module.exports = {
      module: {
        loaders: [
          {
            test: /plugin\.css$/,
            loaders: ['style-loader', 'css'],
          },
        ],
      },
    };
    
  • 3. Add the below import line to your component to tell Webpack to inject the style to your component.
    import '@draft-js-plugins/emoji/lib/plugin.css';
  • 4. Restart Webpack.

Configuration Parameters

themeObject of CSS classes with the following keys.
emoji:CSS class for the emoji wrapper.
emojiSuggestions:CSS class for suggestions component.
emojiSuggestionsEntry:CSS class for an entry in the suggestions component.
emojiSuggestionsEntryFocused:CSS class for the focused entry in the suggestions component.
emojiSuggestionsEntryText:CSS class for an entry’s text in the suggestions component.
emojiSuggestionsEntryIcon:CSS class for an entry’s emoji image in the suggestions component.
emojiSelect:CSS class for emoji select component.
emojiSelectButton:CSS class for button to open emoji select popup.
emojiSelectButtonPressed:CSS class for pressed state of button to open emoji select popup.
emojiSelectPopover:CSS class for emoji select popup.
emojiSelectPopoverClosed:CSS class for closed state of the emoji select popup.
emojiSelectPopoverTitle:CSS class for a title of active group in the emoji select popup.
emojiSelectPopoverGroups:CSS class for the emoji groups wrapper in the emoji select popup.
emojiSelectPopoverGroup:CSS class for a group of emojis in the emoji select popup.
emojiSelectPopoverGroupTitle:CSS class for a title of emoji group in the emoji select popup.
emojiSelectPopoverGroupList:CSS class for a group emoji list in the emoji select popup.
emojiSelectPopoverGroupItem:CSS class for a group emoji list item in the emoji select popup.
emojiSelectPopoverToneSelect:CSS class for tone select in the emoji select popup.
Important. The tone select must overlap the emoji select popup so that disable controls of the popup. By default
.emojiSelectPopoverToneSelect {
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  bottom: 0;
  z-index: 2;
}
emojiSelectPopoverToneSelectList:CSS class for a tone select emoji list in the emoji select popup.
emojiSelectPopoverToneSelectItem:CSS class for a tone select emoji list item in the emoji select popup.
emojiSelectPopoverEntry:CSS class for an emoji entry in the emoji select popup (including tone select).
emojiSelectPopoverEntryFocused:CSS class for the focused emoji entry in the emoji select popup (including tone select).
emojiSelectPopoverEntryIcon:CSS class for an emoji entry’s image in the emoji select popup (including tone select).
emojiSelectPopoverNav:CSS class for a group navigation in the emoji select popup.
emojiSelectPopoverNavItem:CSS class for a group navigation item in the emoji select popup.
emojiSelectPopoverNavEntry:CSS class for an entry of the group navigation in the emoji select popup.
emojiSelectPopoverNavEntryActive:CSS class for active state of the group navigation entry in the emoji select popup.
emojiSelectPopoverScrollbarOuter:CSS class for the outer scrollbar box in the emoji select popup.
emojiSelectPopoverScrollbar:CSS class for scrollbar in the emoji select popup.
emojiSelectPopoverScrollbarThumb:CSS class for scrollbar thumb in the emoji select popup.
positionSuggestionsDeprecated, use popperOptions instead The function can be used to manipulate the position of the popover containing the suggestions. It receives one object as arguments containing the visible rectangle surrounding the decorated search string including the colon. In addition the object contains prevProps, prevState, state & props. An object should be returned which can contain all sorts of styles. The defined properties will be applied as inline-styles.
popperOptionsThis options will be used to initialize popper.js. Read in detail about it here.
priorityList
These entries will be show first in the EmojiSuggestions dropdown after typing `:`. Must be an object which must contain Emoji entries used by JoyPixels e.g.
priorityList: {
  ':see_no_evil:': ["1f648"],
  ':raised_hands:': ["1f64c"],
  ':100:': ["1f4af"],
}
selectGroups
Emoji select groups specification. Must be an array of objects, which declare each group: title, icon (can be a string or React element), array of emoji categories from JoyPixels e.g.
selectGroups: [{
  title: 'Society',
  icon: '👥',
  categories: ['people', 'food', 'travel'],
}, {
  title: 'Objects & symbols',
  icon: '❤️',
  categories: ['objects', 'symbols'],
}]
selectButtonContentContent of button which opens emoji select popup. (Default content is ☺)
toneSelectOpenDelayTime delay before opening tone select. (Default value is 500 ms)
useNativeArtIf set to true, uses host system art for emojis instead of JoyPixels art. Default value is false.
emojiImageIf provided the passed component is used to render the preview image for the suggestions. If this parameter is set the useNativeArt is ignored. You can use this component to implement your own emoji library. It receives the following props: emoji, unicode and theme
emojiInlineTextIf provided the passed component is used to render the emojis in the text. If this parameter is set the useNativeArt is ignored. You can use this component to implement your own emoji library. It receives the following props: decoratedText, className, children and theme
disableInlineEmojisDisables the suggestion popover for emojis in the editor.

EmojiSuggestions

The EmojiSuggestions component is part of the plugin and should placed somewhere in the JSX after the Editor. It takes the following props:
onSearchChangeA callback which is triggered whenever the search term changes. The first argument is an object which contains the search term in the property value.
onOpenA callback which is triggered whenever the suggestions popover opens.
onCloseA callback which is triggered whenever the suggestions popover closes.

EmojiSelect

The EmojiSelect is another component of the plugin. It takes the following props:
onOpenA callback which is triggered whenever the emoji popover opens.
onCloseA callback which is triggered whenever the emoji popover closes.
closeOnEmojiSelectIf set to true the popup is closed after an emoji is selected, otherwise it will stay open.

Simple Emoji Example

SimpleEmojiEditor.js
import React, { Component } from 'react';
import Editor, { createEditorStateWithText } from '@draft-js-plugins/editor';
import createEmojiPlugin from '@draft-js-plugins/emoji';
import editorStyles from './editorStyles.module.css';

const emojiPlugin = createEmojiPlugin();
const { EmojiSuggestions, EmojiSelect } = emojiPlugin;
const plugins = [emojiPlugin];
const text = `Cool, we can have all sorts of Emojis here. 🙌
🌿☃️🎉🙈 aaaand maybe a few more here 🐲☀️🗻 Quite fun!`;

export default class SimpleEmojiEditor extends Component {
  state = {
    editorState: createEditorStateWithText(text),
  };

  onChange = (editorState) => {
    this.setState({
      editorState,
    });
  };

  focus = () => {
    this.editor.focus();
  };

  render() {
    return (
      <div>
        <div className={editorStyles.editor} onClick={this.focus}>
          <Editor
            editorState={this.state.editorState}
            onChange={this.onChange}
            plugins={plugins}
            ref={(element) => {
              this.editor = element;
            }}
          />
          <EmojiSuggestions />
        </div>
        <div className={editorStyles.options}>
          <EmojiSelect />
        </div>
      </div>
    );
  }
}
editorStyles.js
.editor {
  box-sizing: border-box;
  border: 1px solid #ddd;
  cursor: text;
  padding: 16px;
  border-radius: 2px;
  margin-bottom: 2em;
  box-shadow: inset 0px 1px 8px -3px #ABABAB;
  background: #fefefe;
}

.editor :global(.public-DraftEditor-content) {
  min-height: 140px;
}

.options {
  margin-bottom: 20px;
}

Custom Emoji Example with native emojis

SimpleEmojiEditor.js
import React, { Component } from 'react';
import Editor, { createEditorStateWithText } from '@draft-js-plugins/editor';
import createEmojiPlugin from '@draft-js-plugins/emoji';
import editorStyles from './editorStyles.module.css';

const emojiPlugin = createEmojiPlugin({
  useNativeArt: true,
});
const { EmojiSuggestions, EmojiSelect } = emojiPlugin;
const plugins = [emojiPlugin];
const text = `Cool, we can have all sorts of Emojis here. 🙌
🌿☃️🎉🙈 aaaand maybe a few more here 🐲☀️🗻 Quite fun!`;

export default class CustomEmojiEditor extends Component {
  state = {
    editorState: createEditorStateWithText(text),
  };

  onChange = (editorState) => {
    this.setState({
      editorState,
    });
  };

  focus = () => {
    this.editor.focus();
  };

  render() {
    return (
      <div>
        <div className={editorStyles.editor} onClick={this.focus}>
          <Editor
            editorState={this.state.editorState}
            onChange={this.onChange}
            plugins={plugins}
            ref={(element) => {
              this.editor = element;
            }}
          />
          <EmojiSuggestions />
        </div>
        <div className={editorStyles.options}>
          <EmojiSelect closeOnEmojiSelect />
        </div>
      </div>
    );
  }
}