Draft.jsで絵文字(サロゲートペア )をEntityにして良い感じに削除をできるようにする方法
Draft.jsで絵文字を扱うと削除した時にいい感じに消えてくれない問題が発生します。
その解決法にたどり着くまでに地味に時間がかかったので備忘録をかねて書きます
問題
例えばdraft.jsで4人家族の絵文字を消そうとすると、3人家族になったりします
👩👩👧👦
=> 👩👩👧
この問題はdraft.jsでサロゲートペアの絵文字を扱うと発生してしまいます
これを解決する方法として、Draft.jsの Entity というものがあります
Entity
メタデータを使用してテキストの範囲に注釈を付けるために使用するエンティティシステムについて説明します。
エンティティは、スタイル付きテキストを超えるレベルの豊かさをもたらします。リンク、メンション、
および埋め込みコンテンツはすべて、エンティティを使用して実装できます。
といったもので、指定した文字の範囲に役割を与えたり、複数の文字列を一つの文字?として扱うことが可能です
デモ + コード
そしてデモとコードをCodeSandboxで用意しました
解説
ざっくり説明すると
初期化時、文字入力時、コピペ時、IMEの入力(コンポジットモード)が終わった時に操作した文字列の絵文字を正規表現で開始と終了のindexを取得して、EntityのIMMUTABLEというものに変換しています。
こうすることで、一つの文字列として扱うことができ削除の問題を解決できます。
引数に渡している正規表現を変えることで他のEntity化の用件にも対応できると思います
もう少し詳しく書くと、最終的に変更されたContentBlockから絵文字を見つけてEntity化し、操作履歴を誤魔化すために、一度UndoしてからPushだとかいろいろしてたりします。細かく話すとDraft.jsの構造の話になって面倒なので割愛
最後に
ググってもいい感じの記事にたどりつけなかったので、誰かの役に立てるとありがたい
最後にDraft.jsを触った感想ですが、これよりいい感じのライブラリはないものか
メンテが殆どされていないのと、不具合があったり、IMEのイベントまわりがうまく制御されていないのか、ちょっと変化ことをしようとすると日本語とかでバグったりする