Giter Site home page Giter Site logo

serebrov / emoji-mart-vue Goto Github PK

View Code? Open in Web Editor NEW
266.0 4.0 46.0 76.84 MB

One component to pick them all (performance improvements) 👊🏼

Home Page: https://serebrov.github.io/emoji-mart-vue/

License: BSD 3-Clause "New" or "Revised" License

CSS 8.51% JavaScript 75.51% Vue 15.86% Dockerfile 0.12%
vuejs emoji-picker

emoji-mart-vue's Introduction

Build Status - CircleCI

codecov

This project is a fork of https://github.com/jm-david/emoji-mart-vue with many performance fixes, tests and structural code changes. See the changelog for details.

The original component was very slow to show/destroy, around 2 seconds to show and even a bit longer to destroy, so it was unusable in a popup.

This was the reason to fork and change it, the demo is here, use the "Show / hide the picker" button to see create/destroy performance

The original project has been forked from emoji-mart which was written for React.


Emoji Mart (Vue) is a Slack-like customizable
emoji picker component for VueJS
DemoChangelog

Demo app

Live demo app: https://serebrov.github.io/emoji-mart-vue/ Demo application code is under the ./docs folder.

Installation

Install from npm: npm install --save emoji-mart-vue-fast.

It is also possible to install directly from github (could be useful for forks): npm install --save serebrov/emoji-mart-vue#5.4.9.

Here is the list of releases.

Vue 3 Support

Component works with Vue 3, here is a simple demo app.

Live demo: https://serebrov.github.io/emoji-mart-vue3-demo/.

See also: #88.

Quick Example

<template>
  <div class="row">
    <Picker :data="emojiIndex" set="twitter" @select="showEmoji" />
  </div>

  <div class="row">
    <div>
      {{ emojisOutput }}
    </div>
  </div>
</template>

<script>
// Import data/twitter.json to reduce size, all.json contains data for
// all emoji sets.
import data from "emoji-mart-vue-fast/data/all.json";
// Import default CSS
import "emoji-mart-vue-fast/css/emoji-mart.css";

// Vue 2:
import { Picker, EmojiIndex } from "emoji-mart-vue-fast";
// Vue 3, import components from `/src`:
import { Picker, EmojiIndex } from "emoji-mart-vue-fast/src";

// Create emoji data index.
// We can change it (for example, filter by category) before passing to the component.
let emojiIndex = new EmojiIndex(data);

export default {
  name: "App",
  components: {
    Picker
  },

  data() {
    return {
      emojiIndex: emojiIndex,
      emojisOutput: ""
    };
  },

  methods: {
    showEmoji(emoji) {
      this.emojisOutput = this.emojisOutput + emoji.native;
    }
  }
};
</script>

<style>
.row { display: flex; }
.row > * { margin: auto; }
</style>

Changelog

Major changes comparing to the original emoji-mart-vue:

  • [2023-06-11, v15] Updated to emojis v15, thanks @susnux
  • [2022-07-12, v11] Updated to emojis v14, thanks @Hysterelius!
  • [2021-04-17, v10] Accessibility properties and keyboard controls
  • [2021-03-20, v9] Updated to emojis v13, thanks @sgtaziz!
  • Updated to emojis v12 (see the breaking change note below)

Performance improvements:

  • Reworked emoji index class: use same index (so same data) for all components.
  • Render emojis in categories without Emoji component, there are a lot of emojis to render and there is a noticeable slow down when we render a component per emoji.
  • Frozen objects with emoji data to disable Vue change tracking
  • Do not create EmojiIndex globally, before it was loaded (along with the emoji data) even when it was not actually used
  • Extract CSS into external file, use less inline styles to reduce the amount of generated HTML
  • Fixes in CSS for native unicode emojis ported from the original react project
  • Excluded ./data/all.json from the js bundle (it was always loaded within the bundle even if it is not needed)
  • Updated to babel 7
  • Added tests

Breaking change in v6: removed Emoji and Picker wrappers, renamed NimbleEmoji to Emoji and NimblePicker to Picker. See the Convenience Wrappers section below for details.

Breaking change in v7: switched to Unicode v12 emoji set which results in several breaking changes:

  • Removed 'emojione' set (removed from emoji-datasource by JoyPixels request)
  • Removed 'messenger' set - it was merged into 'facebook' set
  • Changed emoji categories: removed 'Smileys & People', added 'Smileys & Emotions' and 'People & Body' instead

Breaking change in v8:

  • The StaticPicker component is now default (exported as Picker), previous default component renamed to VirtualScrollPicker

Breaking change in v12:

  • The VirtualScrollPicker was removed, see #236.

Original Readme

Not opinionated

Emoji Mart doesn’t automatically insert anything into a text input, nor does it show or hide itself. It simply returns an emoji object. It’s up to the developer to mount/unmount (it’s fast!) and position the picker. You can use the returned object as props for the EmojiMart.Emoji component. You could also use emoji.colons to insert text into a textarea or emoji.native to use the emoji.

Components

Picker

import data from 'emoji-mart-vue-fast/data/all.json'
import { Picker, EmojiIndex } from 'emoji-mart-vue-fast'
let emojiIndex = new EmojiIndex(data)

Import CSS with default styles:

import 'emoji-mart-vue-fast/css/emoji-mart.css'

Note: to have a custom look for the picker, either use own css file without including the standard one or add custom styles on top of standard.

Note: CSS also includes background images for image-based emoji sets (apple, google, twitter, facebook). The images are loaded from the unpkg.com. To use self-hosted emojis sheet, override CSS like this:

/* load twitter sheet from own server */
.emoji-mart-body .emoji-type-image.emoji-set-twitter {
	background-image: url(/img/twitter-5.0.1-sheets-256-64.png);
}

Add the <picker> component to your template:

<picker :data="emojiIndex" set="twitter" />
<picker :data="emojiIndex" @select="addEmoji" />
<picker :data="emojiIndex" title="Pick your emoji…" emoji="point_up" />
<picker :data="emojiIndex" :style="{ position: 'absolute', bottom: '20px', right: '20px' }" />
<picker :data="emojiIndex" 
	:i18n="{ search: 'Recherche', categories: { search: 'Résultats de recherche', recent: 'Récents' } }"
/>
Prop Required Default Description
autoFocus false Auto focus the search input when mounted
color #ae65c5 The top bar anchors select and hover color
emoji department_store The emoji shown when no emojis are hovered, set to an empty string to show nothing
emojiSize 24 The emoji width and height; affects font size for native emoji (it is 80% of emojiSize); also the picker width is cacluated dynamically based on emojiSize
perLine 9 Number of emojis per line. While there’s no minimum or maximum, this will affect the picker’s width.
i18n {…} An object containing localized strings
native false Renders the native unicode emoji
set apple The emoji set: 'apple', 'google', 'twitter', 'facebook'
showPreview true Display preview section
showSearch true Display search section
showCategories true Display categories
showSkinTones true Display skin tones picker
emojiTooltip false Show emojis short name when hovering (title)
skin Forces skin color: 1, 2, 3, 4, 5, 6
defaultSkin 1 Default skin color: 1, 2, 3, 4, 5, 6
pickerStyles Inline styles applied to the root element. Useful for positioning
title Emoji Mart™ The title shown when no emojis are hovered
infiniteScroll true Scroll continuously through the categories
Event Description
select Params: (emoji) => {}
skin-change Params: (skin) => {}

Picker Usage And Native Emoji vs Images

The select event described above can be handled to insert the emoji into the text area or use it in any other way. This component does not enforce the usage pattern and it's up to the application how to handle the emoji after it was selected.

For example:

<picker :data="emojiIndex" @select="this.selectEmoji" />

...

selectEmoji(emoji) {
  // Assuming the `textContainer` method that returns the
  // text container component with `enterText` method.
  const textContainer = this.textContainer()
  // Enter the native emoji
  textContainer.enterText(emoji.native)
}

The above will use emoji.native to insert native emoji into the input.

This is the simplest way to use the component and it works relatively well in latest versions of native browsers and latest operating systems. Here, we rely on native unicode emojis support, which, theoretically, should be handled just like any other unicode characters.

In practice, the support for native unicode emoji is still not perfect: unicode emoji characters are part of the font and the font needs to be colorful. But there is no yet a single standard for color fonts implemented by browsers, so the browser leaves emoji rendering to the operating system.

This way, how the emoji will look depends on the operating system and native unicode emoji will look different on different platforms. Also older operating system versions don't not support all the emojis that are currently in the unicode standard, so it may be necessary to limit emojis to some smaller subset.

More consistent solution is also more complex: we can use emoji.colons to insert emoji in the "colons" syntax (such as :smile:) and use regular expressions to find and render the colons emoji as images.

In this case the application can keep text emoji representation and replace before rendering wherever needed (browser, mobile app, email).

The good part here is that we get rid of most of the problems, related to unicode, we work with plain text. For example, in the database the application could have a text like "Hello 😄" which will be turned into emoji with javascript and even if we leave it as a text (due to the bug or lack of javascript support), it will still make sense.

The bad part is that conflicts are possible - if someone enters the :smile: text, it will turn into emoji.

The emoji.getPosition() might be useful in this case to get the emoji position on the emoji sprite sheet.

The replacement can be done approximately like this:

const COLONS_REGEX = new RegExp(
  '([^:]+)?(:[a-zA-Z0-9-_+]+:(:skin-tone-[2-6]:)?)',
  'g'
)

/**
 * Replace emojis insdie the `text` with `<span>`s.
 */
export function wrapEmoji(text: string): string {
  return text.replace(COLONS_REGEX, function(match, p1, p2) {
    const before = p1 || ''
    // We add "data-text='{emoji.native}'", don't replace it
    if (endsWith(before, 'alt="') || endsWith(before, 'data-text="')) {
      return match
    }
    let emoji = emojiIndex.findEmoji(p2)
    if (!emoji) {
      return match
    }
    return before + emojiToHtml(emoji)
  })
  return text;
}

/**
 * Convert Emoji to HTML to represent it as an image.
 */
export function emojiToHtml(emoji: Emoji): string {
  let style = `background-position: ${emoji.getPosition()}`
  // The src="data:image..." is needed to prevent border around img tags.
  return `<img data-text="${emoji.native}" alt="${
    emoji.colons
  }" src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" class='emoji-text' style="${style}">`
}

Another solution is to use emoji.native to insert native emoji and then find and replace them with images.

In this case, the application can keep the native emoji in the database and replace with images where needed - in this case, it can do the replacement for browser, but keep unicode emoji for native app.

The good side here is that conflicts are unlikely, we have native unicode emoji as a part of the text and replace them with images for better browser / os support. It means that if browsers improve the color font support in the future, we can just remove the image replacement part and the rest will be working.

The replacement can be done like this (using the emoji-regex package):

// npm install emoji-regex
import emojiRegex from 'emoji-regex'

import data from 'emoji-mart-vue-fast/data/all.json'
import { EmojiIndex } from 'emoji-mart-vue-fast'

const unicodeEmojiRegex = emojiRegex()

export function wrapEmoji(text: string): string {
  return text.replace(unicodeEmojiRegex, function(match, offset) {
    const before = text.substring(0, offset)
    if (endsWith(before, 'alt="') || endsWith(before, 'data-text="')) {
      // Emoji inside the replaced <img>
      return match
    }
    // Find emoji object by native emoji.
    let emoji = emojiIndex.nativeEmoji(match)
    if (!emoji) {
      // Can't find unicode emoji in our index
      return match
    }
    // See `emojiToHtml` function above.
    return emojiToHtml(emoji)
  })
}

Here we can use emojiIndex.nativeEmoji(emoji_char) to get the emoji object by native emoji and then convert it to the HTML image.

I18n

search: 'Search',
notfound: 'No Emoji Found',
categories: {
  search: 'Search Results',
  recent: 'Frequently Used',
  smileys: 'Smileys & Emoticon',
  people: 'People & Body',
  nature: 'Animals & Nature',
  foods: 'Food & Drink',
  activity: 'Activity',
  places: 'Travel & Places',
  objects: 'Objects',
  symbols: 'Symbols',
  flags: 'Flags',
  custom: 'Custom',
}

Sheet sizes

Sheets are served from unpkg, a global CDN that serves files published to npm. Note: URLs for background images are specified in the css/emoji-mart.css.

Set Size (sheetSize: 16) Size (sheetSize: 20) Size (sheetSize: 32) Size (sheetSize: 64)
apple 334 KB 459 KB 1.08 MB 2.94 MB
facebook 322 KB 439 KB 1020 KB 2.50 MB
google 301 KB 409 KB 907 KB 2.17 MB
twitter 288 KB 389 KB 839 KB 1.82 MB

Datasets and Custom Emojis

While the default setup assumes all.json usage with all sets available, you may want to include only a single set data to reduce the size of your bundle.

Set Size (on disk)
all 570 KB
apple 484 KB
facebook 421 KB
google 483 KB
twitter 484 KB

To use these data files (or any other custom data), use the Picker component like this:

import data from 'emoji-mart-vue-fast/data/facebook.json'
import { Picker, EmojiIndex } from 'emoji-mart-vue-fast'
let index = new EmojiIndex(data)
<picker set="facebook" :data="data" />

Using EmojiIndex, it is also possible to control which emojis data is included or excluded via constructor parameters:

Param Default Description
include [] Only load included categories. Accepts I18n categories keys. Order will be respected, except for the recent category which will always be the first.
exclude [] Don't load excluded categories. Accepts I18n categories keys.
custom [] Custom emojis
recent Pass your own frequently used emojis as array of string IDs
recentLength Set the number of emojis for the recent category.
emojisToShowFilter ((emoji) => true)

Categories for exclude and include parameters are specified as category id, that are present in data arrays.

Avaiable categories are: people, nature, foods, activity, places, objects, symbols, flags.

For example:

import data from 'emoji-mart-vue-fast/data/facebook.json'
import { Picker, EmojiIndex } from 'emoji-mart-vue-fast'

let emojisToShowFilter = function(emoji) {
	// check the emoji properties, see the examples of emoji object below
	return true // return true to include or false to exclude
}
let include = ['people', 'nature']
// or exclude:
// let exclude = ['flags']

const custom = [
	{
		name: 'Octocat',
		short_names: ['octocat'],
		text: '',
		emoticons: [],
		keywords: ['github'],
		imageUrl: 'https://assets-cdn.github.com/images/icons/emoji/octocat.png?v7',
	},
]

let index = new EmojiIndex(data, {
	emojisToShowFilter,
	include,
	exclude,
	custom,
})

Examples of emoji object:

{
  id: 'smiley',
  name: 'Smiling Face with Open Mouth',
  colons: ':smiley:',
  text: ':)',
  emoticons: [
    '=)',
    '=-)'
  ],
  skin: null,
  native: '😃'
}

{
  id: 'santa',
  name: 'Father Christmas',
  colons: ':santa::skin-tone-3:',
  text: '',
  emoticons: [],
  skin: 3,
  native: '🎅🏼'
}

{
  id: 'octocat',
  name: 'Octocat',
  colons: ':octocat',
  text: '',
  emoticons: [],
  custom: true,
  imageUrl: 'https://assets-cdn.github.com/images/icons/emoji/octocat.png?v7'
}

Keyboard Controls

When the cursor is in the search field, the Picker component allows to select the emoji with arrow keys. The selection is confirm with enter, which will emit the selected event (same as when the emoji is clicked with mouse).

Emoji

import data from 'emoji-mart-vue-fast/data/all.json'
import { Emoji, EmojiIndex } from 'emoji-mart-vue-fast'
<emoji :data="index" emoji=":santa::skin-tone-3:" :size="32" />
<emoji :data="index" emoji="santa" set="twitter" :size="32" />
<emoji :data="index" :emoji="santaEmojiObject" :size="32" />

<script>
import data from 'emoji-mart-vue-fast/data/all.json'
let index = new EmojiIndex(data)

export default {
  computed: {
    santaEmojiObject() {
      return index.findEmoji(':santa:')
    },
  },
}
</script>
Prop Required Default Description
emoji Either a string or an emoji object
size The emoji width and height.
native false Renders the native unicode emoji
fallback Params: (emoji) => {}
set apple The emoji set: 'apple', 'google', 'twitter', 'facebook'
sheetSize 64 The emoji sheet size: 16, 20, 32, 64
backgroundImageFn ((set, sheetSize) => `https://unpkg.com/[email protected]/sheet_${set}_${sheetSize}.png`) A Fn that returns that image sheet to use for emojis. Useful for avoiding a request if you have the sheet locally.
skin 1 Skin color: 1, 2, 3, 4, 5, 6
tooltip false Show emoji short name when hovering (title)
tag span HTML tag to use, span by default, set to button for clickable emojis.
Event Description
select Params: (emoji) => {}
mouseenter Params: (emoji) => {}
mouseleave Params: (emoji) => {}

Unsupported emojis fallback

Certain sets don’t support all emojis (i.e. Facebook don’t support :shrug:). By default the Emoji component will not render anything so that the emojis’ don’t take space in the picker when not available. When using the standalone Emoji component, you can however render anything you want by providing the fallback props.

To have the component render :shrug: you would need to:

function emojiFallback(emoji) {
	return `:${emoji.short_names[0]}:`
}
<emoji set="facebook" emoji="shrug" :size="24" :fallback="emojiFallback" />

Headless search

The Picker doesn’t have to be mounted for you to take advantage of the advanced search results.

import { EmojiIndex } from 'emoji-mart-vue-fast'
import data from 'emoji-mart-vue-fast/data/all.json'

const emojiIndex = new EmojiIndex(data)
emojiIndex.search('christmas').map((o) => o.native)
// => [🎄, 🎅🏼, 🔔, 🎁, ⛄️, ❄️]

With custom data

import data from 'emoji-mart-vue-fast/data/facebook'
import { EmojiIndex } from 'emoji-mart-vue-fast'

let emojiIndex = new EmojiIndex(data)
emojiIndex.search('christmas')

Storage

By default EmojiMart will store user chosen skin and frequently used emojis in localStorage. That can however be overwritten should you want to store these in your own storage.

import { store } from 'emoji-mart-vue-fast'

store.setHandlers({
	getter: (key) => {
		// Get from your own storage (sync)
	},

	setter: (key, value) => {
		// Persist in your own storage (can be async)
	},
})

Possible keys are:

Key Value Description
skin 1, 2, 3, 4, 5, 6
frequently { 'astonished': 11, '+1': 22 } An object where the key is the emoji name and the value is the usage count
last 'astonished' (Optional) Used by frequently to be sure the latest clicked emoji will always appear in the “Recent” category

Features

Powerful search

Short name, name and keywords

Not only does Emoji Mart return more results than most emoji picker, they’re more accurate and sorted by relevance.

summer

Emoticons

The only emoji picker that returns emojis when searching for emoticons.

emoticons

Results intersection

For better results, Emoji Mart split search into words and only returns results matching both terms.

high-five

Fully customizable

Anchors color, title and default emoji

customizable-color
pick-your-emoji

Emojis sizes and length

size-and-length

Default skin color

As the developer, you have control over which skin color is used by default.

skins

It can however be overwritten as per user preference.

customizable-skin

Multiple sets supported

Apple / Google / Twitter / Facebook

sets

Convenience Wrappers

The original project had convenience wrappers for Emoji and Picker components that make the usage a bit simpler. But, since they are using all.json for data, that resulted in bigger bundle sizes as all.json was also included into the any app that is using emoji picker, even if it doesn't need all kinds of emojis.

Original components were removed and included here as an example.

Picker component wrapper with default settings:

<script>
import data from 'emoji-mart-vue-fast/data/all.json'
import { EmojiIndex } from 'emoji-mart-vue-fast/src/utils/emoji-data'
import EmojiMartPicker from 'emoji-mart-vue-fast/src/components/Picker'

import { PickerProps } from 'emoji-mart-vue-fast/src/utils/shared-props'

let index = new EmojiIndex(data)

export default {
  functional: true,
  props: {
    ...PickerProps,
    data: {
      type: Object,
      default() {
        return index
      },
    },
  },
  render(h, ctx) {
    let { data, props, children } = ctx

    return h(EmojiMartPicker, { ...data, props }, children)
  },
}
</script>

Emoji component wrapper with default settings:

<script>
import data from 'emoji-mart-vue-fast/data/all.json'
import { EmojiIndex } from 'emoji-mart-vue-fast/src/utils/emoji-data'
import EmojiMartEmoji from 'emoji-mart-vue-fast/src/components/Emoji'

import { EmojiProps } from 'emoji-mart-vue-fast/src/utils/shared-props'

export default {
  functional: true,
  props: {
    ...EmojiProps,
    data: {
      type: Object,
      default() {
        let index = new EmojiIndex(data)
        return index
      },
    },
  },
  render(h, ctx) {
    let { data, props, children } = ctx

    return h(EmojiMartEmoji, { ...data, props }, children)
  },
}
</script>

Development

Build the component and the demo app.

# Build the component and watch for file changes.
$ npm run build
# Build the demo app and watch for file changes.
$ npm run dev:docs

Open docs/index.html in browser to see the demo.

Or serve the dir (with npx and http-server:

npx http-server ./docs

And open http://127.0.0.1:8080/.

Updating emoji

Update emoji-datasource in package.json.

Run npm install to update packages.

Rebuild data with npm run build.

If needed, update sheet columns in src/utils/emoji-data.js to reflect emoji-datasource (usually found here).

Update tests with npm run jest -- -u, then run tests and prettier (below).

Push changes to GitHub.

Tests

Run tests with npm run jest.

To debug tests, run npm run jest-debug and then open chrome://inspect in Chrome and open the node inspector client from there.

Code formatting with prettier: npm run prettier.

Building

# Checkout master branch, update version
git checkout master
# Edit package.json, update `version` field
vim package.json
git add package.json

# Build
nvm use v20
NODE_ENV=production npm run build
npm run dev:docs

# Add build files
git add dist/
git add docs/

# Commit and push changes.
git commit -m "Update version to X.Y.Z"
git push origin HEAD

# Tag the new release (same as package.json version), add the description for tag
# Hint: refer PRs with #17 (PR id) to later have links to PRs in github releases
git tag X.Y.Z -a

# Push the tags
git push origin --tags

# Publish to npm with `npm publish`

## 🎩 Hat tips!

Original react emoji picker: [missive/emoji-mart](https://github.com/missive/emoji-mart).
Vue port: [jm-david/emoji-mart-vue](https://github.com/jm-david/emoji-mart-vue)

Powered by [iamcal/emoji-data](https://github.com/iamcal/emoji-data) and inspired by [iamcal/js-emoji](https://github.com/iamcal/js-emoji).<br>
🙌🏼  [Cal Henderson](https://github.com/iamcal).

emoji-mart-vue's People

Contributors

ai avatar ajbeaven avatar apotheosis91 avatar bniwredyc avatar chadoh avatar dependabot[bot] avatar etiennelem avatar gargron avatar hysterelius avatar iamsaksham avatar jm-david avatar kesoji avatar marcopolo avatar n-filatov avatar nicksarafa avatar nolanlawson avatar npmcdn-to-unpkg-bot avatar samkelleher avatar savardc avatar scotato avatar serebrov avatar snowyu avatar sonicdoe avatar susnux avatar thomaash avatar trun avatar vierkantor avatar vinnymac avatar vrizo avatar zulfio 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  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

emoji-mart-vue's Issues

Consider removing or making vue-virtual-scroller optional

While vue-virtual-scroller helps getting some additional performance, it is not critical and component worked fast enough without it.
The disadvantage of the virtual scroller is that it adds complex HTML structure which is harder to customize (for example, it is complex to style the scroll bar).

JS fiddle?

Hello, I was trying to work around this vue component but just wondering , is there any JS fiddle available for this. As it is a bit confusing to read the docs.
Thanks

Some Emojis aren't being displayed properly

I don't see any pattern on which ones work and which won't, neither do I know when this became an issue.

Some of the broken Emojis are (but not limited to) these:

  • 🧊 (ice_cube)
  • 🧏 (deaf_person)
  • 🧉 (mate_drink)

Switching between native, apple, google etc. sometimes fixes the Emoji in the component, but not the generated Emoji when clicked.

It's even visible on the official demo page:

image

Tested in FF & Chrome on Mac and with Chrome on Win10.

emoji size when using native fonts option

When using the native font option on Windows the unicode characters are not monospaced and vary in width. Emojis are not displayed nicely in columns then.

I am suggesting to add with and height to the css like the following:

span.emoji-mart-emoji {
  width: 36px;
  height: 36px;
}

See also:
image

Scrolling directly to 'flags' results in incorrect scroll position

Hi,

First off, thanks for this amazing fast version of emoji-mart-vue! 😄

When using it in one of my project I noticed that the scrolling to the 'symbols' and 'flags' categories by clicking the category doesn't scroll to the correct height (only on initial load and as first 'click'). In the demo, the problem only occurs when clicking the 'flags' category:

Problem:
image

What I expect:
image

It only happens on the initial load, clicking immediately on the category. As mentioned, in my project the bug occurs for both the 'symbols' and 'flags' category, in the demo only for 'flags', but I think it is the same bug. Also as mentioned, when you already clicked on any of the other categories first, it behaves correctly.

In the original demo (emoji-mart-vue) it works correctly.

It is a minor bug and not really bothering me, but a fix for it sometime would be nice of course 😃

Thanks!

not working with latest vite project

got following error

[vite] Internal server error: Failed to resolve import "./Emoji". Does the file exist?

thats regular issue check this out vitejs/vite#178

just add .vue end of file path

export { default as Anchors } from './anchors.vue'
export { default as Category } from './category.vue'
export { default as Preview } from './preview.vue'
export { default as Search } from './search.vue'
export { default as Skins } from './skins.vue'
export { default as Emoji } from './Emoji.vue'
export { default as Picker } from './Picker.vue'
``

EmojiList should be keyboard accessible

When focusing on the emoji-picker the user should be able to use arrow-keys or tab to navigate through the list of emojis.

A similar change was made to the main parent of this project (emoji-mart)
Issue: missive#218
PR: missive#284

It would be great if a similar change would be made in this project!

[Feature] Dark theme support

Emoji Mart has added support for light and dark themes, exposed through the theme prop. Is it possible to get support for that here?

Categories displaying wrong because of vue-virtual-scroller

I use this package in Quasar Framework dialog:

<q-dialog v-model="emojiPickerDialog">
	<emoji-picker :data="emojiIndex" :emojiSize="24" :native="true" @select="selectEmoji"></emoji-picker>
</q-dialog>

Here is what I get, emoji categories are not displayed properly:

image

BUT, when I enter any string in the search field:

image

And then press backspace until the search field is empty again, all goes as it should be:

image

I believe it's because of vue-virtual-scroller. Or maybe I am wrong?

Possible solution: remove or make vue-virtual-scroller optional as suggested in #52

Dialog direction

Hi, is it possible to control the direction the dialog displays?

For example, at the moment when I click my button the picker displays below the button / mouse cursor and ends up rendering off of the bottom of the screen. What I would like to do is have the picker render upwards above the button / mouse cursor.

Is this available as a property or should I explore CSS to achieve this?

Many Thanks

SSR support

Hello,

First thanks for your work to make the component much faster.
Now the library doesn't seem to support Server Side Rendering and it will throw the error "Window is not defined".

Is there any plan to support this plugin in SSR mode?

Thanks in advance.

Vue3 support?

Is there any plan to support Vue3? If any, APIs have changed significantly in Vue3, and I wonder how simultaneous support for both Vue 2 and 3 will be realized.

I may want to contribute if possible.

Reseting emoji picker

First of all, thank you for this awesome fork and amazing fast component.

As I am using single instance of Picker with Popper, I would like it to start fresh every time it's opened. I was wandering if I could make Picker to reset scroll and return to the first category after selecting emoji.

I am also willing to help and create a PR modifying onEmojiClick method to change the activeCategory.

Emoji component does not display emoji

Good morning,

I am happy to found a distribution of the emoji mart which picker is way faster than jm-davids one. And I appreciate that you filled the docs! But your emoji component does not seem to work properly, it doesn't show up. I followed your instructions on the docs, but without success.

import { Emoji } from "emoji-mart-vue-fast";`
...
export default {
    components: {
        Emoji
    }
...
<span>BEFORE</span>
<emoji emoji="santa" set="messenger" :size="16"/>
<span>AFTER</span>

image

DOM:

<span>BEFORE</span>
<span class="emoji-mart-emoji" size="16">
  <span class="emoji-set-messenger emoji-type-image" style="background-position: 15.69% 37.25%;"></span>
</span>
<span>AFTER</span>

Maybe you know the reason!

Have a nice day

Emoji position overlap

Hi! Thank you for the good improvement!

Issue is about emoji overlap like this image. (I use emoji picker tag in popup dialog)
When I try original emoji-mart-vue, no overlap shown.
Anyway please look at below screenshot.

State 1: emoji overlap
Screenshot from 2019-07-12 03-21-51

State 1: CSS
Screenshot from 2019-07-12 04-24-12

State 2
After state1, I disabled the check box about emoji-mart line-height(Chrome Dev Tool).
Then overlap has been fixed. (State2)

Screenshot from 2019-07-12 04-27-59

State 2: CSS
Screenshot from 2019-07-12 04-43-43

State 3
And after state 2, I enabled the check box about emoji-mart line-height.
Then overlap NOT shown. Why ? (State3)
The State 1 and State 3 is same about css.
But something different ? It's cause emoji overlap ?
Or this issue related ? (Only last item visible)

Screenshot from 2019-07-12 04-27-59

State 3: CSS
Screenshot from 2019-07-12 04-44-14

EmojiIndex :An exception is thrown

image

import

import 'emoji-mart-vue-fast/css/emoji-mart.css'
import data from 'emoji-mart-vue-fast/data/apple.json'
import { Picker, EmojiIndex } from 'emoji-mart-vue-fast'

use

      i18n: {
        categories: {
          search: '搜索结果',
          recent: '经常使用',
          smileys: '心情',
          people: '人物',
          nature: '动物 & 大自然',
          foods: '食物 & 饮料',
          activity: '活动',
          places: '旅行 & 地标',
          objects: '物体',
          symbols: '符号',
          flags: '国旗',
          custom: '自定义',
        }
      }
...
    const emojiIndex = new EmojiIndex(data, {
      i18n: this.i18n,
      exclude: ['flags', 'symbols', 'objects', 'activity', 'foods', 'people', 'places']
    })

I exclude places in this example, I get an error

vue.runtime.esm.js?2b0e:1888 Error: Can not find emoji by id: department_store
    at e.value (emoji-mart.js?41fb:1)
    at VueComponent.idleEmoji (emoji-mart.js?41fb:1)
    at Watcher.get (vue.runtime.esm.js?2b0e:4479)
    at Watcher.evaluate (vue.runtime.esm.js?2b0e:4584)
    at Proxy.computedGetter (vue.runtime.esm.js?2b0e:4836)
    at Proxy.eval (emoji-mart.js?41fb:1)
    at VueComponent.Vue._render (vue.runtime.esm.js?2b0e:3548)
    at VueComponent.updateComponent (vue.runtime.esm.js?2b0e:4066)
    at Watcher.get (vue.runtime.esm.js?2b0e:4479)
    at new Watcher (vue.runtime.esm.js?2b0e:4468)

[Feature request] Typescript support

Hi,
Since package is written in javascript, wanted to ask if some types might be added to the project (wether in house or through DefinitelyTyped)

Change dialoug size

The emoji dialoug/box is over rendering , is there a way to controll the the position of the box?

Emoji zwj sequences with native fonts

When using the native font option emoji zwj sequences are not displayed correctly.

Its producing html like this:

<span class="emoji-set-apple emoji-type-native" style="font-size: 19.2px;">👨&zwj;⚕️</span>

&zwj; should be '\u200D'

image

Window is not defined

Hey @serebrov! I appreciate your hard work on the new and improved version of this library! I installed it and immediately saw the improvements, but after refreshing a few times, I'm now getting a "window is not defined" error from line 335 of the dist/emoji-mart.js file. I'm running VueJS with Nuxt, so I'm not sure if that could relate to this issue, but just wanted to raise a flag. I've spent an hour or so troubleshooting, but will continue to see if I can find the root cause.

Category Anchor Highlighting does not correspond to actual position in scroller.

There is an issue with the Emoji Mart Category Anchors. They do not update properly, as you scroll the emoji-picker. I took a small screencast to demonstrate the problem:

Kapture 2020-07-17 at 11 05 52

The "People & Body" category becomes highlighted while I'm still at the very beginning of "Smileys & Emotion", etc.
The screencast was taken on https://serebrov.github.io/emoji-mart-vue/, but is also reproducible in my local project.

It was taken with Chromium 84 on macOS 10.15. However, this bug is also reproducible in all other tested browser / os combinations. It is not limited to the "native" emoji set, but also to all others.

Updated emoji set

Will this project be updated with the newest emojis that include bald and red head emojis?

Switch to StaticPicker as a default component

Currently, the Picker component uses virtual scroller for additional performance, although it also is a source of issues (#50, #57, #77).

At the same time, as I remember, it didn't add significant performance boost, so it should be OK if the default Picker was "static" (not using the virtual scroller) and we could keep and additional VirtualScrollPicker component as a more performant option, for the cases where this is really needed.

Cannot read property 'observe' of null

Hi, i've switched from emoji-mart-vue to emoji-mart-vue-fast, but on the first load of the page, i recieve this message. While if i refresh the page all works fine.

Cannot read property 'observe' of null

what am i missing ?

Calculation of width from perLine not matching

The calculation of the picker-width out of the perLine-prop seems a bit off? Probably not respecting the padding between emojis?
-> On the example, perLine is set to 9, but only shows 7 emojis per line.

However, might indeed be hard to calculate that, especially, if the padding between emojis might change with emoji-size? 🤔

Greets :)
Jonas

EDIT: Recognized on v10.0.1 😉

Emoji-mart-vue crashes Chrome on Android

Hi, so as title says, when you open emoji picker using open dialog button on demo page it freezes for 5-25 seconds and then you are able to scroll and select emoji. But after a while or if you open emoji picker again Chrome freezes, is not responding and there's a popup that says "Chrome is unresponsive" and I need to force close it. I have this issue on demo page and my project as well. I tried using Picker and StaticPicker but it didn't help. I can reproduce it every time.

Samsung Note 10+ Android 10
Chrome 85.0.4183.127 (latest version)
I tried it with old LG V30 with same results.

Vue 2.6.11
emoji-mart-vue-fast version 7.0.2 and also tested on my project older versions: 6.0.0 and 5.4.15

emojiSize is ignored; always 24

Removed. Figured out the problem with "emojiSize" is that jQuery puts attributes to lower case. I needed to write the property as emoji-size

Exclude of categories not correctly working

new EmojiIndex(data, { exclude: ['recent'] }) does not exclude the recent category.
Instead, new EmojiIndex(data, { exclude: ['people'] }) excludes the recent and people category.

Additionally, after showing the Picker the first category is shown (correctly), but the second category is selected in the view. For example, with every category enabled it shows the recent category, but the people category is selected.

Not working when want to use only messenger icon data

Hi,

i try to only use messenger data but it fail.

import data from 'emoji-mart-vue-fast/data/messenger.json'
import { Picker, EmojiIndex } from 'emoji-mart-vue-fast'
import 'emoji-mart-vue-fast/css/emoji-mart.css'
let emojiIndex = new EmojiIndex(data)

And the template

<template>
  <Picker
    set="messenger"
    :data="emojiIndex"
  />
</template>

No error in console but nothing displayed in the picker

Needing data if using native

So I have the general setup:

import { Picker, EmojiIndex } from 'emoji-mart-vue-fast';
...
public ei = new EmojiIndex(data, {recentLength: 8, exclude: ['flags', 'symbols']});


and in my vue template I have:
<Picker :emoji-size="21" :perLine="9" :native="true" :showPreview="false" :data="ei" @select="insertEmoji" class="emoji-picker" v-show="emojiPickerOpen" ></Picker>

The question is: because I'm using :native="true" do I actually need to grab the emojis.json file?

Keyboard controls and custom alt/title texts

We are currently using this package on websites which needs to be WCAG2.1 compliant. In order to be compliant, you need to be able to control everything with keyboard-only.

Is it possible to add keyboard control to this package? Right now you can't select or cycle trough the emojis using keyboard only.

Also is it possible to add custom titles/alt texts to the emojis?

big bundle size - 458 KB

HI, THANKS FOR THIS FAST PLUGIN .
STILL WHEN I BUILD ITS THE HEAVIEST CHUNK

image

ANY IDEAS TO IMPROVE PERFORMANCE ?

Cannot read property 'length' of null

This error occurs when user switches between emoji categories by clicking top panel categories icons and have filled search field.
This is for StaticPicker by the way.
image

[v10] Issues with the Stylesheet's "hidden" and Tailwind

Hey there!
Thank you for maintaining this package!

With the recent update, the stylesheet includes a global hidden class, which breaks frameworks like TailwindCSS that defines its own hidden and relies on its internal order where the class is defined for overwrites etc.

It would be awesome if we could find a solution, so that the component does not expose any global css classes.

Thank you!

Exclude all.json in bundle when not used

I would like to ask if there is a possible way to exclude all.json from the bundle when building if it is not used in any way? The file size (465.91Kb) almost exceed 500Kb and it is big for entrypoint.

image from Build Analyzer
image

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.