

How to Add Emoji Picker in Text Fields
source link: https://tahazsh.com/how-to-add-emoji-picker-in-textarea
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

How to Add Emoji Picker in Text Fields
Emojis have become a basic part of any writing these days. And I have no doubt that, sooner or later, you'll need to have them supported in one of your applications.
I was looking, the other day, for a package to add a slack-like emoji picker in one of my textarea fields. But, unfortunately, I didn't find a nice one that integrates easily with VueJS. However, I did find a package that provides a component that displays only the emoji picker and give me the needed information about the emoji to add.
So I decided to create a simple component that uses that picker to add the clicked emojis in the textarea field. And in this tutorial I'm going to show you how I did it.
Preparing the component
In this step, we're going to create our component and add the textarea into it along with the necessary bindings.
We'll name the component TextareaEmojiPicker
. So create TextareaEmojiPicker.vue
in your components directory and put this into it:
<template>
<div class="textarea-emoji-picker">
<textarea
ref="textarea"
class="textarea"
:value="value"
@input="$emit('input', $event.target.value)"
></textarea>
</div>
</template>
<script>
export default {
props: {
value: {
type: String,
default: ''
}
}
}
</script>
<style scoped>
* {
box-sizing: border-box;
}
.textarea-emoji-picker {
position: relative;
width: 400px;
margin: 0 auto;
}
.textarea {
width: 100%;
min-height: 300px;
outline: none;
box-shadow: none;
padding: 10px 28px 10px 10px;
font-size: 15px;
border: 1px solid #BABABA;
color: #333;
border-radius: 2px;
box-shadow: 0px 2px 4px 0 rgba(0,0,0,0.1) inset;
resize: vertical;
}
.emoji-mart {
position: absolute;
top: 33px;
right: 10px;
}
.emoji-trigger {
position: absolute;
top: 10px;
right: 10px;
cursor: pointer;
height: 20px;
}
.emoji-trigger path {
transition: 0.1s all;
}
.emoji-trigger:hover path {
fill: #000000;
}
.emoji-trigger.triggered path {
fill: darken(#FEC84A, 15%);
}
</style>
For now, we only have the textarea element in this component. To allow for v-model
on this component, we made it accept value
prop and emit an input
event.
Try to use that component in your page, like this:
<template>
<div class="home-page">
<textarea-emoji-picker v-model="text"/>
</div>
</template>
<script>
import TextareaEmojiPicker from './TextareaEmojiPicker'
export default {
name: 'HomePage',
components: { TextareaEmojiPicker },
data () {
return {
text: ''
}
}
}
</script>
<style scoped>
.home-page {
padding-top: 50px;
}
</style>
Adding the emoji picker
There's an excellent emoji picker component called Emoji Mart. The main job of this component is to display a nice picker (similar to slack) and return an emoji
object when an emoji is clicked. This emoji object contains, among other things, the unicode value that represents it — we'll use this value to display them in our textarea.
This component was originally created in React, but since we're using Vue here, we'll install the vue version of it:
npm install --save emoji-mart-vue
Now include that component in TextareaEmojiPicker
component:
<script>
import { Picker } from 'emoji-mart-vue'
export default {
components: { Picker },
// ...
}
Then, use it at the top of our component:
<div class="textarea-emoji-picker">
<picker
title="Pick your emoji..."
emoji="point_up"
/>
If you check the browser now, you'll see the picker open — which does nothing at the moment.
Adding a trigger button
Obviously, we shouldn't keep the picker open by default. We should instead have a button to toggle it.
Before we add that button, we need to have a flag to determine if the picker should open or not. Define it in data()
, like this:
data () {
return {
showEmojiPicker: false
}
}
Now let's add the trigger button below <picker/>
:
<span
class="emoji-trigger"
:class="{ 'triggered': showEmojiPicker }"
@mousedown.prevent="toggleEmojiPicker"
>
<svg
style="width:20px;height:20px"
viewBox="0 0 24 24"
>
<path fill="#888888" d="M20,12A8,8 0 0,0 12,4A8,8 0 0,0 4,12A8,8 0 0,0 12,20A8,8 0 0,0 20,12M22,12A10,10 0 0,1 12,22A10,10 0 0,1 2,12A10,10 0 0,1 12,2A10,10 0 0,1 22,12M10,9.5C10,10.3 9.3,11 8.5,11C7.7,11 7,10.3 7,9.5C7,8.7 7.7,8 8.5,8C9.3,8 10,8.7 10,9.5M17,9.5C17,10.3 16.3,11 15.5,11C14.7,11 14,10.3 14,9.5C14,8.7 14.7,8 15.5,8C16.3,8 17,8.7 17,9.5M12,17.23C10.25,17.23 8.71,16.5 7.81,15.42L9.23,14C9.68,14.72 10.75,15.23 12,15.23C13.25,15.23 14.32,14.72 14.77,14L16.19,15.42C15.29,16.5 13.75,17.23 12,17.23Z" />
</svg>
</span>
Note how we attached a mousedown.prevent
event listener to that button instead of click
. We did this to prevent the textarea from losing its focus when the picker opens.
Now let's define that method, like this:
methods: {
toggleEmojiPicker () {
this.showEmojiPicker = !this.showEmojiPicker
}
}
Lastly, we should use that flag on our picker via v-show
:
<picker
v-show="showEmojiPicker"
title="Pick your emoji..."
emoji="point_up"
/>
Just in case you're wondering, we used v-show
instead of v-if
to avoid instantiating the picker each time it's toggled. So we just instantiate it once and then keep toggling it using css display:none
, which is clearly faster.
Adding emojis
Now we get to the last piece of our component. As I mentioned earlier, we need to read the unicode value of the clicked emoji. And to get that value, we have to listen to @select
event on <picker>
component:
<picker
v-show="showEmojiPicker"
title="Pick your emoji..."
emoji="point_up"
@select="addEmoji"
/>
Now let me show you how to define that method and then explain it:
addEmoji (emoji) {
const textarea = this.$refs.textarea
const cursorPosition = textarea.selectionEnd
const start = this.value.substring(0, textarea.selectionStart)
const end = this.value.substring(textarea.selectionStart)
const text = start + emoji.native + end
this.$emit('input', text)
textarea.focus()
this.$nextTick(() => {
textarea.selectionEnd = cursorPosition + emoji.native.length
})
}
We add the emoji in three steps. First, we split the text in the textarea into two pieces: from the beginning to the current cursor position and from the current cursor position to the end. We named them start
and end
, respectively.
Second, we concatenate the first part, the emoji, and the second part together and store them in text
constant. And then we use that value to update the current text in the textarea.
Third, we re-focus on the textarea, and then move the cursor after the added emoji.
Note how we needed to reposition the cursor in the $nextTick
callback to wait until the focusing is done in the previous tick.
That's it! Now you should have an emoji picker in your textarea.
Note: the code of this demo can be found on GitHub.
Recommend
-
40
Emoji Button Vanilla JavaScript emoji picker :sunglasses: Emoji Button turns an ordinary button in...
-
7
Emoji pickers are ubiquitous. It se...
-
12
emoji-picker-element
-
12
What does this thing do? JavaScript bloat is more real today than it ever was. Sites continuously get bigger as more (often redundant) libraries are thrown to solve new problems. Until of-course, the big rewrite happens....
-
8
Interweave Emoji Picker A React based emoji picker powered by Interweave and Emojibase. Supports the following features:
-
9
emoji-picker-element/Picker.scss at 9975b341e96ef996f20576d25305771fe7c2cc77 · nolanlawson/emoji-picker-element · GitHub
-
13
emoji-picker-element <emoji-picker></emoji-picker> A lightweight emoji picker, distributed as a web component. Features: Supports
-
14
Thanks! I saw shadow parts but somehow missed that the browser support was actua...
-
16
rn-emoji-keyboard A lightweight, fully customizable emoji picker, written as React Native component (without native elements). Designated to be user and developer friendly!
-
8
emoji-picker-element <emoji-picker></emoji-picker> A lightweight emoji picker, distributed as a web component. Features: Supports
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK