WARNING: THIS SITE IS A MIRROR OF GITHUB.COM / IT CANNOT LOGIN OR REGISTER ACCOUNTS / THE CONTENTS ARE PROVIDED AS-IS / THIS SITE ASSUMES NO RESPONSIBILITY FOR ANY DISPLAYED CONTENT OR LINKS / IF YOU FOUND SOMETHING MAY NOT GOOD FOR EVERYONE, CONTACT ADMIN AT ilovescratch@foxmail.com
Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions .changeset/brave-dragons-write.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
---
'slate-react': patch
---

Fix Android handwriting input where first stroke commits prematurely on empty lines (e.g., '我' becomes '一我').

**Cause:** When writing the first character of an empty line, Android handwriting triggers childList mutations (creating new DOM structure). These mutations get restored by RestoreDOM during React re-render, which interrupts the IME composition session.

**Fix:** Skip flush during composition only when at the first character of an empty line. This targeted fix preserves normal onChange behavior for other scenarios while preventing the handwriting issue.

Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,35 @@ export function createAndroidInputManager({
action.run()
}

// Helper: Check if cursor is at the first character of an empty line
const isAtEmptyLineFirstChar = (): boolean => {
const { selection, children } = editor
if (!selection) return false

const { anchor } = selection
// offset should be 0 or 1 (first char)
if (anchor.offset > 1) return false

// Get the block node at current path
const blockPath = anchor.path.slice(0, 1) // Get top-level path
const blockNode = children[blockPath[0]]
if (!blockNode) return true

// Check if this line/block is empty or has only one character
const text = Node.string(blockNode)
return text.length <= 1
}

const flush = () => {
// FIX: Only skip flush during composition for empty line first char scenario.
// Android handwriting input triggers childList mutations when writing the first
// character of an empty line. These mutations get restored by RestoreDOM, which
// interrupts the IME composition and causes premature commits.
// See: https://github.com/ianstormtaylor/slate/issues/5979
if (IS_COMPOSING.get(editor) && isAtEmptyLineFirstChar()) {
return
}

if (flushTimeoutId) {
clearTimeout(flushTimeoutId)
flushTimeoutId = null
Expand Down