2021/06/16
フロントエンド絵文字ピッカーの実装方法
Slack、Notion、Zennなどで見るような絵文字ピッカーをHTML上で実装する方法です。
Emoji Buttonというパッケージを使います。
Emoji Buttonの特徴
- OS依存の絵文字 or Twemojiの絵文字のどちらかを選択可能。
- 絵文字を名前で検索できる機能。
- 肌色などのバリエーションに対応。
- 最近選択した絵文字を表示可能。
- Tabキーや矢印キーでの操作が可能。
- 3つのテーマを設定可能(ライトテーマ、ダークテーマ、ユーザーのOS環境に合わせたテーマ)
- 独自の画像やGIFを絵文字として追加可能。
- 独自の処理を追加可能。例) ランダムで任意の絵文字を選択する等。
- 言語を指定可能。
使い方
「絵文字」ボタンを押した時にピッカーが表示されるようにします。
HTMLの準備
まずはHTMLファイルを作ります。今回はindex.htmlという名前にします。
~/index.html
<button class="emoji-trigger">絵文字</button>
ボタンを1つ表示します。このボタンにはemoji-trigger
というクラス名をつけました。
Emoji Buttonのインストール
npm initで初期化してpackage.jsonを作ります。
~/
$ npm init -y
続いて、webpackと共にemoji-buttonをインストールします。
~/
$ npm i @joeattardi/emoji-button webpack
これでnode_modulesの中にインストールされます。
JSファイルの作成
emoji-buttonに関する処理を記述するJavaScriptファイルを用意します。
srcディレクトリ内にindex.jsを作成します。
~/
$ mkdir src
$ touch src/index.js
index.jsは以下のようになります。
~/src/index.js
import { EmojiButton } from '@joeattardi/emoji-button';
const picker = new EmojiButton();
// クラス名がemoji-triggerの要素を取得
const trigger = document.querySelector('.emoji-trigger');
picker.on('emoji', selection => {
// 選択された絵文字をtriggerのinnerHTMLに設定する
trigger.innerHTML = selection.emoji;
});
// triggerがクリックされたら、絵文字ピッカーの表示/非表示を切り替える
trigger.addEventListener('click', () => picker.togglePicker(trigger));
JSファイルのビルドと読み込み
npx webpack
コマンドを実行すると、index.jsがビルドされてdist/main.jsが生成されます。
ビルド
$ npx webpack
生成されたmain.jsをindex.htmlで読み込みます。
index.html
<button class="emoji-trigger">絵文字</button>
<script src="dist/main.js"></script>
特に設定をしない限りは、jsファイルを修正するたびにnpx webpackでビルドする必要があるので注意してください。
ここまでの設定で絵文字ピッカーの表示ができるようになります!
カスタマイズ
絵文字ピッカーのデザインなどをカスタマイズする例です。
ドキュメントに従えばそれほど難しくありません。
~/src/index.js
const picker = new EmojiButton({
// I18N: 検索窓のplaceholder、該当絵文字がなかった場合のメッセージ
i18n: {
search: '絵文字を検索..',
notFound: '絵文字が見つかりませんでした..'
},
// Themes: ユーザーの環境に合わせてライト・ダークを切り分ける
theme: 'auto',
// Positioning: 画面右上に絵文字ピッカーを表示する
position: {
top: '0',
right: '0'
},
// Variants: 肌色の選択をしない
showVariants: false,
// z-indexの指定
zIndex: 1,
});
プラグイン
プラグインを自作して絵文字ピッカーの挙動をカスタマイズすることもできます。
例えば、「ランダムボタン」を押すと絵文字がランダムに選択されるようにしたい場合は、以下のように実装できます。
~/src/index.js
import { EmojiButton } from '@joeattardi/emoji-button';
const trigger = document.querySelector('.emoji-trigger');
const randomPickerPlugin = {
render(picker) {
// ランダムボタンを生成
const button = document.createElement('button');
button.innerHTML = 'ランダム';
// ランダムボタンが押された時: 画面に表示されている全絵文字の中からランダムに1つ選択してtriggerの値として設定
button.addEventListener('click', () => {
const emojis = document.getElementsByClassName("emoji-picker__emoji")
trigger.innerHTML = emojis[Math.floor(Math.random() * emojis.length)].textContent
});
return button;
}
}
const picker = new EmojiButton({
// プラグインとしてrandomPickerPlugin関数を設定
plugins: [randomPickerPlugin]
});
picker.on('emoji', selection => {
trigger.innerHTML = selection.emoji;
});
trigger.addEventListener('click', () => picker.togglePicker(trigger));
このような動きになります。
翻訳・日本語対応
絵文字名を日本語で扱いたい時は、emoji-button-locale-dateが使えます。
npm install @roderickhsiao/emoji-button-locale-data
でインストールした上で以下のように修正します。
~/src/index.js
import { EmojiButton } from '@joeattardi/emoji-button';
// 追加
import jaEmojiData from '@roderickhsiao/emoji-button-locale-data/dist/ja'
const picker = new EmojiButton({
// 追加
emojiData: jaEmojiData
});
// クラス名がemoji-triggerの要素を取得
const trigger = document.querySelector('.emoji-trigger');
picker.on('emoji', selection => {
trigger.innerHTML = selection.emoji;
});
// triggerがクリックされたら、絵文字ピッカーの表示/非表示を切り替える
trigger.addEventListener('click', () => picker.togglePicker(trigger));
import文とemojiData: jaEmojiData
を追加するだけで、日本語対応してくれます。