-
Notifications
You must be signed in to change notification settings - Fork 3.3k
fix(slate-react): prevent premature flush during composition for Andr… #5981
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix(slate-react): prevent premature flush during composition for Andr… #5981
Conversation
🦋 Changeset detectedLatest commit: ae1ab7b The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
1e926e7 to
068ee68
Compare
|
@aiden-art What are the implications of this for the timing of Can you also check if the mentions example still works with this change? The combobox should update itself while composition is still in progress. Many Android devices also use composition for writing English text, so this could break a lot of features if we're not careful. |
|
@12joan Thanks for the thoughtful review! Yes, this change does affect
I've tested the mentions example and it works correctly. I'll attach a video demonstrating this. Record_2025-11-27-19-45-50_40deb401b9ffe8e1df2f1c.mp4Here's a video demonstrating the fix for Android handwriting input: Record_2025-11-27-19-54-26_40deb401b9ffe8e1df2f1c.mp4 |
|
@aiden-art Thanks for confirming that about It looks like in your video where you try out the mentions example, your device isn't using composition for English text, which I believe is common in Gboard and perhaps other keyboard applications running on recent versions of Android. Samsung Keyboard and older versions of Gboard also use composition for English, which you can tell by the underline while typing. I've just tried your PR on my older Samsung phone, and the combobox doesn't show up until I explicitly end composition. I'm seeing the same thing on a Samsung Galaxy S23 running on BrowserStack Live. recording.mp4Ideally, it would be great if we could fix this problem without causing any breaking changes. If changing the way Slate works during composition is unavoidable, then we should make sure that existing patterns have valid workarounds, and these should be clearly communicated in the changeset and probably the docs too. |
d58df45 to
e521f49
Compare
…oid handwriting input Fixes ianstormtaylor#5979 On Android devices, handwriting input on empty lines triggers childList mutations when creating new DOM structure for the first character. These mutations get restored by RestoreDOM during React re-render, which interrupts the IME composition session and causes premature stroke commits (e.g., writing '我' produces '一我'). The fix adds a targeted check in flush() to skip flushing only when: 1. Currently in composition (IS_COMPOSING is true) 2. Cursor is at the first character of an empty line This preserves normal onChange behavior for other scenarios while preventing the handwriting issue on empty lines.
e521f49 to
ae1ab7b
Compare
|
Thanks for your feedback and testing! After detailed log analysis, I found that the issue only occurs when writing the first character of an empty line (including new lines). Root cause: When writing on an empty line, Android handwriting triggers Current fix: Skip flush during composition only when at the first character of an empty line: if (IS_COMPOSING.get(editor) && isAtEmptyLineFirstChar()) { I hope this analysis and approach can help others who encounter similar handwriting input issues on Android. The key insight is that the problem is related to |
Description
On Android devices, using handwriting input (e.g., Sogou Input Method) causes the initial stroke of a character to be committed prematurely. For example, when writing "我", the first stroke "一" is inserted immediately, leading to a final incorrect result of "一我".
The root cause is that Android handwriting IME triggers
compositionStart/compositionEndevents per stroke, unlike keyboard input which only fires these events at the beginning and end of the entire input session. During composition, multiple code paths (handleInput(),scheduleAction(),handleUserSelect()) were callingflush(), which applies pending diffs to the editor viaEditor.insertText(). This DOM modification causes the browser to terminate the current composition session, and the next stroke starts a new composition that appends to the already-committed text rather than replacing it.The fix adds
IS_COMPOSINGchecks inflush(),scheduleAction(), andhandleInput()to prevent flushing during an active composition session. The pending diffs now properly accumulate and are only flushed aftercompositionEndfires.Issue
Fixes: #5979
Checks
yarn test.yarn lint. (Fix errors withyarn fix.)yarn start.)yarn changeset add.)