今回は私が現在開発中のサービスである「emoji日記」で使用している代表的なライブラリをご紹介しよう。
その名も「emoji-mart」である。
このライブラリは最近話題のエンジニアコミュニティサービスである「Zenn」でも使用されているものだ。
各セクションは下記をご確認していただこう。
それではemoji-martの基本的な使い方とAPIをご紹介していこう。
後半では実際に私がemoji-martを使って実装したものもご紹介しよう。
使い方
それでは早速導入方法からご説明しよう。
npmかyarnでライブラリをインストールする。
npm i emoji-mart
# or
yarn add emoji-mart
これだけである。
emoji-martの提供するコンポーネントは2つある。
- Pickerコンポーネント
- Emojiコンポーネント
上記のコンポーネントの基本情報をご紹介しよう。
Pickerコンポーネント
このコンポーネントは書いて時の如く、絵文字のパレット的なものだ。UI/UXも優れたコンポーネントである。公式がデモをweb上に上げているので試していただきたい。
Emojiコンポーネント
このコンポーネントは絵文字単体に特化したコンポーネントである。後にAPIの仕様について綴るが、それらとセットで使うことでいい感じに絵文字を表示できる。絵文字は通常の文字列とは異なり、特殊な文字列としてブラウザに読み込まれている。表示したくても簡単に表示できないことが多々あるので、このコンポーネントを使用することで良い感じに実装できるのだ。
例えば下記をご覧いただこう。
普通に実装した場合 | コンポーネントを使用 |
左はaタグで囲った結果で右はEmojiコンポーネントを使用した結果だ。
こんな感じで絵文字は少々特殊な仕様となっているのだ。
それでは続いてAPIの仕様を簡単にご説明しよう。
APIの仕様
公式のGitHubを参考にしながらAPIの仕様を見てみよう。
Pickerコンポーネント
5つほど例を挙げてご説明しよう。 これが実際ソースコードである。
① <Picker set='apple' />
② <Picker onSelect={this.addEmoji} />
③ <Picker title='Pick your emoji…' emoji='point_up' />
④ <Picker style={{ position: 'absolute', bottom: '20px', right: '20px' }} />
⑤ <Picker i18n={{ search: 'Recherche', categories: { search: 'Résultats de recherche', recent: 'Récents' } }} />
それではそれぞれの解説をしていこう。
set | onSelect |
---|---|
これはどの種類の絵文字を使うか指定できる。デフォルトではAppleだが他にも、「Twitter・Google・Facebook」等の絵文字も洗濯することが可能だ。 | onSelectはPickerで選んだ絵文字のデータを取得することができる。後に絵文字のデータについてもご紹介するのでそこで確認していただこう。 |
title | style | i18 |
---|---|---|
titleではPickerのデフォルトテキストを設定することができる。ここは自由に決めてもらって構わないだろう。 | styleではcssを使った装飾が可能だ。自分好みにPickerを装飾してUIを実装しよう。 | i18はPickerに表示される言語をカスタマイズすることができる。もちろん絵文字を使うこともできる。 |
Emojiコンポーネント
こちらはPickerコンポーネントと比べてシンプルに3つご紹介しよう。
<Emoji emoji={{ id: 'santa', skin: 3 }} size={16} />
<Emoji emoji=':santa::skin-tone-3:' size={16} />
<Emoji emoji='santa' set='apple' size={16} />
emoji | size | skin |
---|---|---|
emojiは絵文字のデータに含まれるIDを埋め込めばその絵文字が表示される。このプロパティは必須である。 | sizeは絵文字のサイズを指定するものである。数値のみ入力できる。こちらも必須である。 | skinは主に人間や身体の絵文字を使うときにあると便利なプロパティだ。必須ではない。 |
emojiのAPIデータ
ではemojiのデータについてご紹介しよう。 JSONで提供されているため扱いやすい。
emojiData: {
"id": "woman-swimming",
"name": "Woman Swimming",
"colons": ":woman-swimming::skin-tone-4:",
"emoticons": [],
"unified": "1f3ca-1f3fd-200d-2640-fe0f",
"skin": 4,
"native": "🏊🏽♀️"
}
これらを使ってEmojiコンポーネントでアウトプットするわけだ!
では続いて私が現在開発中のプロダクトでの実装をご確認いただこう。
emoji日記での実装
こちらもPickerコンポーネントとEmojiコンポーネントで分けてご紹介しよう。
Pickerコンポーネント
import "emoji-mart/css/emoji-mart.css";
import { Picker, Emoji } from "emoji-mart";
import { useTheme } from "next-themes";
import React, { useState, VFC } from "react";
type Props = {
selectEmoji: any;
emojiValue: {
id: string;
native: string;
colons: string;
emotions: string[];
name: string;
skin: number | null;
};
};
export const EmojiPicker: VFC<Props> = (props) => {
const { theme } = useTheme();
const { native } = props.emojiValue;
const onSelect = (emoji) => {
props.selectEmoji({ ...emoji });
};
return (
<div>
<Picker
theme={theme === "light" ? "light" : "dark"}
showPreview={false}
onSelect={(emoji) => onSelect({ ...emoji })}
set="apple"
style={{ color: "lightgray", width: "100%" }}
title={
<p className="text-base">
{native ? (
<span className="text-base">
{native} こちらでよろしいですか?
</span>
) : (
"emojiを選んでください"
)}
</p>
}
i18n={{
search: "emoji検索",
clear: "クリア",
notfound: "emojiが見つかりません",
skintext: "スキンカラー",
categories: {
search: "検索結果",
recent: "オススメのemoji😘",
smileys: "顔文字 & アクション",
people: "人 & 身体",
nature: "動物 & 自然",
foods: "食べ物 & 飲み物",
activity: "ゲーム & スポーツ",
places: "旅行 & 場所",
objects: "オブジェクト",
symbols: "シンボル",
flags: "国旗",
custom: "カスタム",
},
}}
/>
</div>
);
};
ポイントとしてはthemeだろうか。これもPickerコンポーネントで提供されているダークモードの設定ができるものだ。emoji日記ではダークモードの切り替えを実装しているためこちらも実装した。
コンポーネントの仕様は単純でPickerを使って選択した絵文字のデータを、ページコンポーネントに渡してあげてる。
Emojiコンポーネント
import Link from "next/link";
import { Emoji } from "emoji-mart";
import { VFC } from "react";
type Props = {
id: number;
emojiId: string;
emojiSkin: number | null;
};
export const HomeEmoji: VFC<Props> = (props) => {
return (
<Link
key={props.id}
href={{
pathname: "/posts/[postId]",
query: { postId: props.id },
}}
>
<a className="m-5 p-5 transition duration-200 text-center text-4xl sm:text-4xl hover:bg-gray-100 dark:hover:bg-semiDark border-fontDark rounded-lg">
{!props.emojiSkin ? (
<Emoji emoji={props.emojiId} set="apple" size={35} />
) : (
<Emoji
emoji={props.emojiId}
set="apple"
size={35}
skin={props.emojiSkin}
/>
)}
</a>
</Link>
);
};
こちらもやっていることはシンプルで、保存した絵文字のデータを元にEmojiコンポーネントで表示しているだけだ。あとはskinがあるか無いかで表示する絵文字を切り分けているくらいだ。
終わりに
いかがだっただろうか?
昨今のSNSでは「いいね機能」が主流ではあるが、私はもっと表現の幅を広げたいと感じている。Slackで言うところのスタンプ的なもので絵文字を使ってリアクションすることで、SNS特有の誤解が減りユーザビリティが上がると思うのだ。
また、今回は紹介していないが絵文字をカスタムしてオリジナルの絵文字を作り出すこともできるのだ。今後のemoji日記の仕様に「ユーザーが自作した絵文字を登録して使える」ようにするつもりなので、完成を楽しみにしていただきたい。
絵文字系の機能を実装する際はこちらの「emoji-mart」を使用していただいてはいかがだろう。少し容量は大きいが良い感じに実装できるだろう。