DjangoBrothers BLOG ✍️

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を追加するだけで、日本語対応してくれます。