Skip to content

Instantly share code, notes, and snippets.

@zarpio
Forked from edwardlorilla/emoji-picker.markdown
Created April 7, 2022 17:17
Show Gist options
  • Select an option

  • Save zarpio/6cb6bac6372ea3d5618769912d16d721 to your computer and use it in GitHub Desktop.

Select an option

Save zarpio/6cb6bac6372ea3d5618769912d16d721 to your computer and use it in GitHub Desktop.

Revisions

  1. @edwardlorilla edwardlorilla created this gist Mar 19, 2018.
    7 changes: 7 additions & 0 deletions emoji-picker.markdown
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,7 @@
    emoji picker
    ------------


    A [Pen](https://codepen.io/edward1995/pen/PRWqoQ) by [Edward Lance Lorilla](https://codepen.io/edward1995) on [CodePen](https://codepen.io).

    [License](https://codepen.io/edward1995/pen/PRWqoQ/license).
    39 changes: 39 additions & 0 deletions index.html
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,39 @@
    <div id="app">
    <div class="wrapper">
    <textarea class="regular-input" v-model="input"></textarea>
    <emoji-picker @emoji="append"></emoji-picker>
    </div>
    </div>

    <template id="emoji-picker">
    <div>
    <div class="emoji-invoker" @click="toggle">
    <svg height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg">
    <path d="M0 0h24v24H0z" fill="none"/>
    <path d="M11.99 2C6.47 2 2 6.48 2 12s4.47 10 9.99 10C17.52 22 22 17.52 22 12S17.52 2 11.99 2zM12 20c-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8-3.58 8-8 8zm3.5-9c.83 0 1.5-.67 1.5-1.5S16.33 8 15.5 8 14 8.67 14 9.5s.67 1.5 1.5 1.5zm-7 0c.83 0 1.5-.67 1.5-1.5S9.33 8 8.5 8 7 8.67 7 9.5 7.67 11 8.5 11zm3.5 6.5c2.33 0 4.31-1.46 5.11-3.5H6.89c.8 2.04 2.78 3.5 5.11 3.5z"/>
    </svg>
    </div>
    <div
    class="emoji-picker"
    v-if="display.visible"
    :style="{ top: display.y + 'px', left: display.x + 'px' }"
    v-click-outside="hide"
    >
    <div class="emoji-picker__search">
    <input type="text" v-model="search" ref="search">
    </div>
    <div>
    <div v-for="(emojis, category) in this.searchedEmojis">
    <h5>{{ category }}</h5>
    <div class="emojis">
    <span
    v-for="(emoji, emojiName) in emojis"
    @click="insert(emoji)"
    :title="emojiName"
    >{{ emoji }}</span>
    </div>
    </div>
    </div>
    </div>
    </div>
    </template>
    130 changes: 130 additions & 0 deletions script.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,130 @@
    Vue.component('emoji-picker', {
    data() {
    return {
    emojis: {
    'Frequently used': {
    'thumbs_up': '👍',
    '-1': '👎',
    'sob': '😭',
    'confused': '😕',
    'neutral_face': '😐',
    'blush': '😊',
    'heart_eyes': '😍',
    },
    'People': {
    'smile': '😄',
    'smiley': '😃',
    'grinning': '😀',
    'blush': '😊',

    },
    'Nature': {
    'dog': '🐶',
    'wolf': '🐺',
    'cat': '🐱',

    },
    'Objects': {
    'bamboo': '🎍',
    'gift_heart': '💝',
    'dolls': '🎎',
    'school_satchel': '🎒',
    'mortar_board': '🎓',

    },
    'Places': {
    'house': '🏠',
    'house_with_garden': '🏡',
    'school': '🏫',

    },
    'Symbols': {
    'keycap_ten': '🔟',
    '1234': '🔢',
    'symbols': '🔣',

    },
    },
    search: '',
    display: {
    x: 0,
    y: 0,
    visible: false,
    },
    }
    },
    template: '#emoji-picker',
    computed: {
    searchedEmojis() {
    if (this.search) {
    const obj = {}

    for (const category in this.emojis) {
    obj[category] = {}

    for (const emoji in this.emojis[category]) {
    if (new RegExp(`.*${this.search}.*`).test(emoji)) {
    obj[category][emoji] = this.emojis[category][emoji]
    }
    }
    }

    return obj
    }

    return this.emojis
    },
    },
    methods: {
    insert(emoji) {
    this.$emit('emoji', emoji)
    },
    toggle(e) {
    this.display.visible = ! this.display.visible
    this.display.x = e.clientX
    this.display.y = e.clientY
    if (this.display.visible) this.$nextTick(() => this.$refs.search.focus())
    },
    hide() {
    this.display.visible = false
    },
    },
    directives: {
    'click-outside': {
    bind(el, binding, vNode) {
    if (typeof binding.value !== 'function') {
    return
    }

    const bubble = binding.modifiers.bubble
    const handler = (e) => {
    if (bubble || (! el.contains(e.target) && el !== e.target)) {
    binding.value(e)
    }
    }
    el.__vueClickOutside__ = handler

    document.addEventListener('click', handler)
    },
    unbind(el, binding) {
    document.removeEventListener('click', el.__vueClickOutside__)

    el.__vueClickOutside__ = null
    },
    },
    },
    })

    new Vue({
    el: '#app',
    data() {
    return {
    input: '',
    }
    },
    methods: {
    append(emoji) {
    this.input += emoji
    },
    },
    })
    1 change: 1 addition & 0 deletions scripts
    Original file line number Diff line number Diff line change
    @@ -0,0 +1 @@
    <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.15/vue.js"></script>