From bfcdb835366e6f2772d5a935dbce52159b96aae7 Mon Sep 17 00:00:00 2001
From: Arturo Fonseca <49870466+arturo32@users.noreply.github.com>
Date: Wed, 13 Aug 2025 05:20:00 -0300
Subject: Fix deletion of composed emojis in web composer (#8829)

---
 src/view/com/composer/text-input/TextInput.web.tsx | 21 ++++++++++++++++++++-
 1 file changed, 20 insertions(+), 1 deletion(-)

(limited to 'src/view/com/composer/text-input/TextInput.web.tsx')

diff --git a/src/view/com/composer/text-input/TextInput.web.tsx b/src/view/com/composer/text-input/TextInput.web.tsx
index d5db7bcb6..f76c07036 100644
--- a/src/view/com/composer/text-input/TextInput.web.tsx
+++ b/src/view/com/composer/text-input/TextInput.web.tsx
@@ -13,6 +13,7 @@ import {Text as TiptapText} from '@tiptap/extension-text'
 import {generateJSON} from '@tiptap/html'
 import {Fragment, Node, Slice} from '@tiptap/pm/model'
 import {EditorContent, type JSONContent, useEditor} from '@tiptap/react'
+import Graphemer from 'graphemer'
 
 import {useColorSchemeStyle} from '#/lib/hooks/useColorSchemeStyle'
 import {usePalette} from '#/lib/hooks/usePalette'
@@ -214,11 +215,29 @@ export const TextInput = React.forwardRef(function TextInputImpl(
             }
           }
         },
-        handleKeyDown: (_, event) => {
+        handleKeyDown: (view, event) => {
           if ((event.metaKey || event.ctrlKey) && event.code === 'Enter') {
             textInputWebEmitter.emit('publish')
             return true
           }
+          if (event.code === 'Backspace') {
+            const isNotSelection = view.state.selection.empty
+            if (isNotSelection) {
+              const cursorPosition = view.state.selection.$anchor.pos
+              const textBefore = view.state.doc.textBetween(0, cursorPosition)
+              const graphemes = new Graphemer().splitGraphemes(textBefore)
+
+              if (graphemes.length > 0) {
+                const lastGrapheme = graphemes[graphemes.length - 1]
+                const deleteFrom = cursorPosition - lastGrapheme.length
+                editor?.commands.deleteRange({
+                  from: deleteFrom,
+                  to: cursorPosition,
+                })
+                return true
+              }
+            }
+          }
         },
       },
       content: generateJSON(richtext.text.toString(), extensions, {
-- 
cgit 1.4.1

