👻

ReactでZennみたいな絵文字ピッカー作ってみた

2022/06/07に公開

概要

個人開発の中で、zennみたいな絵文字ピッカー作ってみたいな〜と思ったので、実際に作ってみました。

といっても、ピッカーの完成品を提供してくれる専用のライブラリを使ったので、ほとんどimportしてきただけなのですが😇

ライブラリはemoji-picker-reactを使用しました。

https://www.npmjs.com/package/emoji-picker-react

競合のものだと、emoji-martというライブラリもありました。
そちらの方がスター数も多く、絵文字単体のコンポーネントも提供してくれていて、けっこう充実はしていそうでした。

しかし、<Picker />みたいな感じでのコンポーネントの表現ができず(new演算子を使ってねと言われた)、それ以上の調査はすこし面倒だったので、実装難易度が低そうなemoji-picker-reactを選びました。

本記事では、画面上の絵文字をクリックすると、ピッカーが出てきて、選んだ絵文字がそのまま画面に表示されるというラインをゴールといたします。

前提

  • emoji-picker-react: 3.5.1
  • react: 17.0.2
  • typescript: 4.5.5
  • @mui/material: 5.3.1
  • @emotion/react: 11.7.1

手順

手順はとても単純です。

  1. ハンドラー作成
  2. ボタン・モーダル作成
  3. 絵文字ピッカー置く

1. ハンドラー作成

ピッカーの絵文字を押したときのハンドラーを作成します。

ハンドラーの中では、選択した絵文字のデータをsetします。
setするstateの初期値には、なにか好きな絵文字を入れておきます。

2.で、選択した絵文字を表示させるボタンをつくるのですが、最初になにか表示されていた方がzennっぽくていいなと思ったので、こうしています。

本当はランダムに絵文字の初期値をセットできていたら一番よかったのですが、emoji-picker-reactは絵文字単体のコンポーネントは提供していないので、むずかしそうでした(何かアイデアがあれば、コメントで教えてください!)。

ハンドラーのコードはこちらです。

  const [emojiData, setEmojiData] = useState<IEmojiData>({
    activeSkinTone: "neutral",
    emoji: "😇",
    names: [""],
    originalUnified: "",
    unified: "",
  })

  const handleEmojiClick = (
    event: React.MouseEvent<Element, MouseEvent>,
    emojiData: IEmojiData
  ) => {
    setEmojiData(emojiData)
  }

stateであるemojiDataの型はIEmojiDataというものです。
emoji-picker-reactが提供してくれているので、importしましょう。

初期値もIEmojiDataに沿わせる必要がありますが、activeSkinTone以外のプロパティは、空文字が許されているので上記に書いて問題ありません(activeSkinToneはneutralにしておいてください)。

またハンドラー内ではeventに関する処理はないものの、これを入れておかないと、ピッカーにハンドラーを入れる際に型で怒られるので、React.MouseEvent<Element, MouseEvent>という型にして定義しておきましょう。

2. ボタン・モーダル作成

次は、絵文字ピッカーを発火・表示させるためのボタンと、表示の際にピッカーをラップするモーダルを作成します。

モーダルは適当にmuiのものを使っており、その開閉は、1.同様にuseStateで管理しています。
また、emojiData.emojiに具体的な絵文字が入っているので、それはボタンの上に表示させましょう。

ボタンとモーダルのコードはこちらです。


const Hoge = () => {
  const [emojiData, setEmojiData] = useState<IEmojiData>({
    activeSkinTone: "neutral",
    emoji: "😇",
    names: [""],
    originalUnified: "",
    unified: "",
  })
  const [open, setOpen] = useState(false)

  const handleEmojiClick = (
    event: React.MouseEvent<Element, MouseEvent>,
    emojiData: IEmojiData
  ) => {
    setEmojiData(emojiData)
    setOpen(false)
  }

  return (
    <div>
      <Button
        onClick={() => setOpen(true)}
        css={css`
          font-size: 25px;
          border: 1px solid gray;
          width: 50px;
          height: 50px;
        `}
      >
        {emojiData.emoji}
      </Button>
      <Modal
        open={open}
        onClose={() => setOpen(false)}
        css={css`
          display: flex;
          justify-content: center;
          margin-top: 100px;
        `}
      >
        いったんhoge
      </Modal>
    </div>
  )
}

ピッカーが入るところには一旦文言を入れています。

3. 絵文字ピッカー置く

あとはピッカーを置くだけ!!!

完成形

const Hoge = () => {
  const [emojiData, setEmojiData] = useState<IEmojiData>({
    activeSkinTone: "neutral",
    emoji: "😇",
    names: [""],
    originalUnified: "",
    unified: "",
  })
  const [open, setOpen] = useState(false)

  const handleEmojiClick = (
    event: React.MouseEvent<Element, MouseEvent>,
    emojiData: IEmojiData
  ) => {
    setEmojiData(emojiData)
    setOpen(false)
  }

  return (
    <div>
      <Button
        onClick={() => setOpen(true)}
        css={css`
          font-size: 25px;
          border: 1px solid gray;
          width: 50px;
          height: 50px;
        `}
      >
        {emojiData.emoji}
      </Button>
      <Modal
        open={open}
        onClose={() => setOpen(false)}
        css={css`
          display: flex;
          justify-content: center;
          margin-top: 100px;
        `}
      >
        <Picker native onEmojiClick={handleEmojiClick} />
      </Modal>
    </div>
  )
}

スクショで伝える

これが

こうなって

こう!

無事絵文字をピックすることができました。

所感

超かんたんに絵文字ピッカーを作れて、ハッピーでした😂

Discussion