Git Product home page Git Product logo

rm-emoji-picker's Introduction

Why This Emoji Picker?

I wanted a modern looking emoji picker that worked on all modern browsers (IE 9+), gave me the flexibility to control what happens when an emoji is clicked, came with support for contenteditable elements, and didn't deal with the horrible :colon: syntax we've forced on users that just want to see a smiley face!

alt tag

Installation

The best way to install the library is through npm:

npm install rm-emoji-picker

or

yarn add rm-emoji-picker

https://www.npmjs.com/package/rm-emoji-picker

Usage

Include the css file located at dist/emojipicker.css in your html:

<link href="emojipicker.css" rel="stylesheet" type="text/css" />

Next, import and instantiate the emoji picker, which is a UMD module (thanks webpack!).

import EmojiPicker from "rm-emoji-picker";

//First construct an instance of EmojiPicker
const picker = new EmojiPicker();

//Next tell it where to listen for a click, the container it should be appended to, and the input/textarea/contenteditable it needs to work with
const icon      = document.getElementById('my-icon');
const container = document.getElementById('container');
const editable  = document.getElementById('my-input');

picker.listenOn(icon, container, editable);

That's it!

When you want the text back with emojis in unicode format, just call this method:

const text = picker.getText();

If you want to render text with emojis, call this static method (works with colon syntax or unicode):

const emoji_text = EmojiPicker.render('lol! :laughing:')

If you want to support windows operating systems, which have embarrassingly poor support for emojis, you'll want to add the sheets parameter to the constructor like this:

const picker = new EmojiPicker({
    sheets: {
        apple   : '/sheets/sheet_apple_64_indexed_128.png',
        google  : '/sheets/sheet_google_64_indexed_128.png',
        twitter : '/sheets/sheet_twitter_64_indexed_128.png',
        emojione: '/sheets/sheet_emojione_64_indexed_128.png'
    }
});

You can find sheets to use in the sheets folder in this repo.

As promised in my "WHY" section, you can configure it to suit your needs.

Next I'll show you how to construct an EmojiPicker with all of the bells and whistles, but don't worry, you don't NEED all of these options!

const picker = new EmojiPicker({
    //This tells the EmojiPicker that you want to use sprite sheets for operating
    //systems that don't support emoji (sprite sheets are your fastest option).
    //I've included sprite sheets for apple, google, twitter, and emojione emojis in the repo.
    //Feel free to copy those into your web root and provide a path to the files in this option.
    sheets: {
        apple   : '/sheets/sheet_apple_64_indexed_128.png',
        google  : '/sheets/sheet_google_64_indexed_128.png',
        twitter : '/sheets/sheet_twitter_64_indexed_128.png',
        emojione: '/sheets/sheet_emojione_64_indexed_128.png'
    },
    
    //Show the colon syntax in the preview or don't. It may not make sense if you're
    //using a contenteditable element to confuse users with unfamiliar colon syntax
    show_colon_preview: true,

    //If you want your contenteditable to be a single-line input, set this to true
    prevent_new_line : false,

    //The text that will be displayed when no emoji is being hovered over.
    default_footer_message: "Please select an emoji from the list above",

    //Can be "autoplace", "vertical", "horizontal", or a function that takes a tooltip as an argument.
    //The tooltip is an instance of the class in this repo here: https://github.com/RobertMenke/Tooltip-js
    positioning: "autoplace",
    
    //When the user hovers over the top row of icons, do you want them to be shown
    //a tooltip indicating which category the icon represents?
    show_icon_tooltips : true,

    //Callback that occurs when an emoji gets selected. You get back Emoji, EmojiCategory, Node
    callback   : (emoji, category, node) => {
        if(node instanceof HTMLELement){
            node.classList.add('emoji-image')
        }
    },
    
    //This optional callback is called any time the picker is opened.
    onOpen : () => {
        //trigger some event
    },
    
    //This callback is called once the picker has fully parsed and created markup for each emoji
    //and emoji category
    onReady : (categories) => {
        //example of setting a particular category as active and then filtering its contents
        categories.setActiveCategoryByName('Activity');
        picker.active_category.filter((/**Emoji*/emoji) => emoji.matchesSearchTerm(new RegExp("soccer")));
        //some time later programmatically show all emojis
        setTimeout(() => {
            picker.active_category.showAllEmojis();
        }, 3000)
    },

    //Use sprite sheets to display image emojis rather than links to png files (faster).
    //If you want links to the png files see this repo here for examples (library I'm using):
    //https://github.com/iamcal/emoji-data
    use_sheets : true,
    
    //By default we show an magnifying glass icon in the search container, 
    // but if you're not using fontawesome you may want to include your own icon.
    search_icon : '<i class="fa fa-search" aria-hidden="true"></i>',
    
    //Sets of categories and icons that denote sections at the top of the picker.
    // The category names are not arbitrary, they map to the names of categories in data.js. 
    // By default, I'm assuming you're using FontAwesome because, well, why wouldn't you?! 
    // If you want fewer categories, or different icons this is the place to configure that.
    categories: [
        {
            title: "People",
            icon : '<i class="fa fa-smile-o" aria-hidden="true"></i>'
        },
        {
            title: "Nature",
            icon : '<i class="fa fa-leaf" aria-hidden="true"></i>'
        },
        {
            title: "Foods",
            icon : '<i class="fa fa-cutlery" aria-hidden="true"></i>'
        },
        {
            title: "Activity",
            icon : '<i class="fa fa-futbol-o" aria-hidden="true"></i>'
        },
        {
            title: "Places",
            icon : '<i class="fa fa-globe" aria-hidden="true"></i>'
        },
        {
            title: "Symbols",
            icon : '<i class="fa fa-lightbulb-o" aria-hidden="true"></i>'
        },
        {
            title: "Flags",
            icon : '<i class="fa fa-flag-checkered" aria-hidden="true"></i>'
        }
    ]
});

Credit Where Credit Is Due

This library would not be possible without the help of iamcal/js-emoji https://github.com/iamcal/js-emoji and Tim Down, who provided many wonderful Range and Selection answers on stackoverflow http://stackoverflow.com/users/96100/tim-down.

Architecture

There are 5 objects that work together to create and manage the emoji picker:

  1. EmojiPicker - Sets up the UI, dispatches events, and works with the Tooltip API for positioning.
  2. EmojiCategory - parses data from data.js and creates a pane with emojis and a title. Manages Emoji objects that belong to it.
  3. Emoji - parses and makes sense of data for an individual emoji. It creates markup for the emoji display in unicode or as an image. Emoji also sends various events back up to EmojiPicker (hover,click).
  4. EmojiEditor - keeps track of the cursor in contenteditable elements, places emoji as an image, characters, or (in the case of textareas & inputs) text emojis using :colon: syntax (like Slack https://get.slack.help/hc/en-us/articles/202931348-Emoji-and-emoticons).
  5. Converters - deals with the iamcal/js-emoji library to convert emojis into a form we can display to users.

Future

  1. Add frequently used category by logging emoji selections into localStorage.
  2. Add an options inside of the picker to choose which emoji palette (apple, google, twitter, emojione) to use.
  3. Add an option for skin tones.
  4. Update the dataset to unicode 9 (pending OS support).
  5. Update code with flow types and typescript definitions.

Contributing

To get the project up and running locally, follow the instructions here https://github.com/RobertMenke/rm-emoji-picker/wiki/Build-Instructions.

Pull requests are welcome! The best way to get in touch with me is through a github issue.

rm-emoji-picker's People

Contributors

neverthemachineforever avatar robertmenke avatar simonhildebrandt avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

rm-emoji-picker's Issues

Load without building webpack

Hi. Is there any way to load plugin just in browser without webpack?
I'm trying:

var picker = new EmojiPicker();

but got EmojiPicker is not defined

I figure out, that lib is accessible via window.default, but anyway got error: (0 , g.default) is not a function
in:

key: "_getWrapper", value: function () {
    return (0, g.default)('<span class = "emoji-char-wrapper ' + this.hover_color + '" data-name="' + this.full_name + '" data-category="' + this.category + '"></span>')
}

Publish Example

Make the examples directory publically available, e.g. with gh-pages.

Build instructions

While working on #18 I've had some trouble getting the tool to build.

After a few misfires I ran webpack and got a build - but it doesn't seem to have images in it.

Could we get some notes on the actual build process? (Happy to PR changes to the readme, if someone can point me in the right direction. :D )

Hidden Scrollbar

The scrollbar handle/slider for a list of emoji is not visible. it's hidden under the Search bar.

While I see this is to achieve the effect of the emoji scrolling under an opaque header, a user may not realize they can scroll within the popup to reveal additional emoji. I'd favor seeing the scrollbar over the opacity effect if both can't be achieved.

SELECTED event never fired on iOS due to click event not being invoked on mobile devices

This is likely due to the jQuery.click event not firing events on iOS. The events fire like this:

  1. Click emoji #1: #1.MOUSEENTER
  2. Click different emoji #2: #1.MOUSELEAVE #2.MOUSEENTER

A work around in the mean time is:

    var picker = new EmojiPicker(...);
    picker.categories.forEach(function(cat) {
      cat.emojis.forEach(function(emoji) {
        emoji.$emoji.on('touchend.emoji', function() {
          if(emoji._bubble){
            emoji._bubble(picker.defaults.events.SELECTED, emoji);
          }
        });
      });
    });

Show a row of latest used emojis

I saw that you have it under Future "Add frequently used category by logging emoji selections into localStorage.".

I am wondering about the timeline of this.

Run on Chrome version that doesn't support import

I would like to use your widget but I am running Electron, which uses Chromium version 56. The import statement is not supported in Chrome versions less than 60.

I was able to do the following:

var EmojiPicker = require("rm-emoji-picker");

var picker = new EmojiPicker.default();
const icon = mContent.find(".edtAccountAvatar")[0];
const container = mContent.find(".discMessageInputContTop")[0];
const editable = mContent.find(".edtEnableRatingChk")[0];

picker.listenOn(icon, container, editable);

There was no need for the import. The code runs without any issues but when I click on my icon, nothing happens. Nothing is displayed.

Any way to make this work on Chrome versions earlier than 60?

UPDATE:

The DOM hadn't finished loading. I added a delay to wait for the DOM update and then it worked.

Cursor position

when I have several emojis and I want to go back to insert another emoji, I have to press 3 times the keyboard to see the cursor

Requested feature: Optionally encase emoji with element using render method

The unicode emojis appear small. Although I can increase the fontsize, this would make the rest of the text also larger and doesn't look good. One solution is to have the emoji character placed inside of an element such as a span and set the fontsize on the span to be larger. Adding a span however is fairly complex when the emoji gets added from a contenteditable and you have a lot of other text mixed in.

It would be nice if you could extend the render method so that it accepted a second optional parameter that the emoji would get encased in before you returned the rendered text. For example:

let text = EmojiPicker.render("I love cats :smiley_cat: but dogs too", "<span class='cats'>", "</span");

This would render to:

I love cats <span class='cats'>๐Ÿ˜บ</span>

I could then set the fontsize on the "cats" class without affecting the remaining text. Alternatively, you could include a callback in the render function that gets called prior to render function returning the rendered text. The callback would provide the emoji character. The callback could then append and/or prepend stuff to the emoji (such as the span) and return this. You would then use this in the rendered code instead of the emoji character alone.

Support image set selection

Would it be possible to add a configuration var to select which image set to use? I see you can set img_var with js-emoji, but I saw no way to pass that down. Otherwise, everything else works great. This is the only picker I've found that actually works with my build system.

Missing search results

Searches for Symbols 100 and interrobang do not appear in results. It's possible others don't as well, but I stopped after two.

Force picker to use sheets on a Mac

Is it possible to have the picker use the sheet images instead of the unicode characters. I prefer the unicode characters but they are small and while I can change the fontsize, it changes for all the other text which is what I want to avoid. You have the use_sheets : true option but I believe it only works on Windows. I tried it on my Mac but it doesn't do anything.

font-family: initial !important

Setting font-family: initial !important overrides the user's font setting and defaults to the browser's serifed font. The use of serif and sans-serif fonts in the same picker does not look as clean.

The font-family should be set to the same face and size as the word "Search" to appear consistent with the rest of the picker, and not use !important so that the application's stylesheet could override the default setting.

Very large file size for module

I noticed that when I included your picker in my app, the file size went up by 100 mb which is a huge amount. After investigating, I discovered that your app was using the dependency emoji-js which in turn has the dependency emoji-datasource. I removed both of these from my app and your emoji picker worked fine without it. Can you explain why those dependencies are needed? What will I be losing if I leave them out?

Could not find a declaration file for module 'rm-emoji-picker'.

Could not find a declaration file for module 'rm-emoji-picker'. 'e:/vscode/code/chat ui/node_modules/rm-emoji-picker/dist/EmojiPicker.js' implicitly has an 'any' type.
Try npm install @types/rm-emoji-picker if it exists or add a new declaration (.d.ts) file containing declare module 'rm-emoji-picker';ts(7016)
plz, help to solve it

EmojiPicker.js problem

Hi,

I have a problem with this : C:\path\project\node_modules\rm-emoji-picker\dist\EmojiPicker.js:1

capture

so that crash my app... Am i missing somehing ? I said that because they have no issue about this.

Can you help about that please ?

ES6 is obligatory ?

Thanks.

render from symbol/text to emoji

Hi Robert,

Is there any possibility to call function in EmojiPicker object with React to render out from symbol/text to emoji? or is there any function to use EmojiPicker mapping to the sheet in React?

because i using textarea as editor and saving symbol/text in my DB but when display i want to render it to emoji?

Thank you

Footer and Keyword Usage

When hovering over the first emoji, the footer shows grinning. Slack, for example, shows :grinning: to indicate that you can type that into the body of your input field.

If the application does not support entering the keyword into the input field, the footer should not be displayed at all. The current implementation suggests grinning could be typed into the input field and produce an emoji.

Suggest adding a show_footer = true as one setting, where false would hide the footer div if keywords are not supported by the input.

Then, perhaps a second setting: emoji_delimiter = ":" which would wrap around the keyword in the footer if it's displayed.

Bug: event is undefined.

event is undefined error by firefox .

  openPicker() {
        ...
        this._onTooltipClick(tooltip, event);  <- this is undefined.
        ...
  }

and I want to change rm-tooltip#setClickCallback;

Tooltip.prototype.setClickCallback = function(event, func){

    if (event) {
      event.stopPropagation();
    }

    this._unique = 'click.' + new Date().getTime();

    $("html").on(this._unique, event => {
        func.call(this, event.target, this.$tooltip);
    });
};

Remove all content

How can I remove all content within div.contenteditable?
When I write and do line break and at the end I delete all the content stays one or two '


</ div>'

Version bump

I'm having trouble pulling our new version from NPM, and I think it's 'cause I forgot to include a version bump in my PR - sorry. :/

Could we get a version bump and a new package published?

Inline sourceMappingURL on the dist file.

I found out that the source map is included on the dist file. Importing this library, as suggested on the readme, will result it huge bundle file. Could we have it removed?

screen shot 2018-09-03 at 14 53 01

Package fails `yarn check`

In a new directory:

$ yarn add rm-emoji-picker
<success>
$ yarn check
error "rm-emoji-picker" is wrong version: expected "0.4.0", got null

Changing the version number in the package.json from 0.4.01 to 0.4.1 fixes this issue.

Font Awesome 5 icons support

Hey! Im using FontAwesome 5+ on my project,
and the icons inside the emojii drawer is calling some deprecated icons
like fa fa-smile-o or fa fa-futbol-o (mostly '-o' appended classes)

I suggest appending the new classes and leaving the old one as a fallback for FontAwesome 4 Users.
as this (in this order) might work: class="fa fa-smile-o fas fa-smile"

Remove all content

I am using VueJs and Firebase for a chat application, my problem is when I press ENTER after typing in the div.contenteditable I want to delete the contents of the div but it generates two 'div>br' and the cursor to the end of the two div.
Div.contenteditable

<div id="input-container" class="input-container">
    <div class="input-emoji">
        <div id="input-div" class="input-div" @keydown="keyDownTextField" 
contenteditable="true" v-el:container-text focus></div>
    </div>
</div>

Code Javascript

methods: {
      keyDownTextField (e) {
        if (e.keyCode === 13 && e.shiftKey === false) {
          this.sendMessageText()
        }
      },
      sendMessageText () {
        let _temp = _.trimStart(this.picker.getText())
        if (_temp.length > 0) {
          this.clearInputDiv()
          // send message Firebase
        }
      },
      clearInputDiv () {
        const node = document.getElementById('input-div')
        while (node.firstChild) {
          node.removeChild(node.firstChild)
        }
      }
}

And when I use the delete content function it creates two divs within the contenteditable

<div id="input-div" class="input-div" contenteditable="true" focus="">
    <div><br></div>
    <div><br></div>
</div>

picker.getText() Returns HTML with textArea input

When I set the picker to listen on a textarea as the input, calling the picker.getText() method returns a line of html instead of returning the unicode value.

example: <span class="emoji emoji-sizer" style="background-image:url(/emoji-data/img-apple-64/1f61b.png)" data-codepoints="1f61b"></span>

I have noticed that if I change the textarea to an editable div, that this method returns unicode as expected. However, the page I'm working with already has several things relying on this textarea, and I was hoping to avoid reworking the page to work with an editable div if I don't have to.

[windows] picker.getText() returns an HTML instead of unicode

I'm having some trouble to make it work on Windows because getText - which I use to save the unicode into the database - returns an HTML on Windows (using props use_sheets and sheets).

I have no problems with it on Mac, using both textarea/div[contenteditable="true"].

screen shot 2018-01-31 at 14 05 30

screen shot 2018-01-31 at 14 05 39

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.