Skip to content

Ending uncommitted Chinese IME composition moves the caret to the wrong offset #6

Open

Description

@wudidewo12

Description

Ending or interrupting an uncommitted Chinese IME composition can leave the caret at the wrong offset across Slate examples.

This is not limited to the Images example. The same composition/caret issue was manually reproduced on the current local v2 branch in:

  • examples/plain-text
  • examples/richtext
  • examples/images
  • examples/editable-voids
  • examples/inlines
  • examples/mentions
  • examples/tables

The issue happens when Chinese IME composition is started but not committed, then cancelled or interrupted.

Recording

Screenshots attached below:

Local actual behavior:

Live reference expected behavior:

Video attached below:

issue-001-ime-composition-caret-offset.mp4

A short recording should be attached because the bug depends on the live IME composition state and caret movement.

Video walkthrough:

  1. Place the caret inside editable Slate text.
  2. Start typing with a Chinese IME.
  3. Do not commit the composition.
  4. Cancel/interact away from the composition, for example by deleting the composition text, pressing Esc, or clicking elsewhere.
  5. The caret moves to the wrong offset.
  6. Typing the next character confirms that insertion happens from the wrong position.

Sandbox

No standalone sandbox. Reproduced in the Slate examples site.

Local reproduction URL:

http://localhost:3100/examples/images

Reference URL:

https://www.slatejs.org/examples/images

The same issue was manually reproduced in the other examples listed above.

Steps

To reproduce the behavior:

  1. Open a Slate example with editable text, such as examples/plain-text, examples/richtext, or examples/images.
  2. Click inside editable text and note the caret position.
  3. Start typing several Chinese characters using a Chinese IME.
  4. Do not commit the composition.
  5. End or interrupt the uncommitted composition. Confirmed variants include:
    • deleting the composition text
    • pressing Esc
    • clicking elsewhere before committing
  6. Observe the caret position.
  7. Optionally type another character to confirm the next insertion point.

Expectation

The caret should stay at the same logical insertion point where the IME composition began.

If the composition is cancelled or interrupted before commit, the next typed character should insert at that original caret position.

Live reference behavior:

  • On the live Slate examples site, ending or interrupting the uncommitted Chinese IME composition keeps the next insertion point aligned with the original caret position.
  • The next typed character is inserted at the expected position.

Actual behavior

After ending or interrupting the uncommitted Chinese IME composition, the caret moves to the wrong offset.

In the Codex in-app browser the caret appears to move one offset forward. In Chrome, the visible result can be more severe.

The next typed character is inserted at the wrong position.

Local actual behavior:

  • On the local v2 examples site, ending or interrupting the uncommitted Chinese IME composition moves the caret to the wrong offset.
  • Typing the next character confirms that insertion happens from the shifted caret position.

Environment

  • Slate branch: v2
  • Current local commit tested: ce2bd6c6
  • Local examples site: http://localhost:3100
  • Reference examples site: https://www.slatejs.org
  • Browser: Chrome on macOS
  • Input method: Chinese IME
  • OS: macOS

Impact

This affects normal Chinese text entry across multiple Slate examples. Users who cancel, delete, or otherwise interrupt an active IME composition can continue typing from the wrong caret position, which corrupts the intended text insertion point.

Activity

  1. zbeyens commented on May 10, 2026

    @zbeyens
    Member

    🟡 80-94% confidence

    Phase 🧪 Tests 🌐 Browser
    Reproduced ✅ Issue video confirms real Chinese IME candidate/cancel flow ⚠️ Manual Chrome/macOS Chinese IME report only
    Verified 🟢 Chromium cancellation/history/caret proof is green ⚠️ Real OS Chinese IME still needs human repro

    🌐 Browser Check

    • Open http://localhost:3100/examples/images.
    • With Chrome on macOS and a Chinese IME enabled, place the caret inside editable text.
    • Start a Chinese IME composition, do not commit it, then cancel/delete/Esc/click away.
    • Type the next character and confirm it inserts at the original composition-start caret position.
    • Repeat on plain-text, richtext, editable-voids, inlines, mentions, and tables if possible.

    ✅ Outcome

    • Current automated Chromium proof keeps canceled composition text out of history.
    • Current automated Chromium proof keeps text stable after type/delete/cancel composition.
    • Current automated Chromium proof keeps the next typed character anchored after a canceled composition.

    ⚠️ Caveat

    • This issue depends on the native macOS Chinese IME candidate/cancel path. The automated proof covers the browser/runtime cancellation model, but it is not enough to claim full manual IME closure. Please reproduce the steps above in Chrome on macOS with a real Chinese IME; leave this open until that confirms the behavior.

    🏗️ Design

    • Chosen owner: Slate v2 composition/caret runtime behavior.
    • Why not quick patch: no current manual IME repro was available in this pass, and the synthetic cancellation path is already green.
    • Why not broader change: broader IME changes need real OS input-method evidence before we touch stable runtime behavior.

    🧪 Verified

    • cd /Users/zbeyens/git/slate-v2 && PLAYWRIGHT_RETRIES=0 PLAYWRIGHT_BASE_URL=http://localhost:3100 bun playwright playwright/integration/examples/rendering-strategy-runtime.test.ts --project=chromium --grep "does not push canceled IME composition onto history|keeps text stable after type-delete-cancel IME composition|keeps canceled IME caret anchored for the next typed character"
  2. wudidewo12 commented on May 22, 2026

    @wudidewo12
    Author

    Retested manually on current local v2 commit e62c2046; this is still not fully fixed, but the current failure scope appears narrower than the original report.

    Current behavior

    • Previously, the caret could move to the wrong offset whether the Chinese IME composition was committed or not.
    • Now, the uncommitted/canceled path appears improved in the user's manual retest.
    • However, after committing/confirming Chinese IME input, the caret still moves to the wrong offset.

    Current classification

    This issue should remain open. The original uncommitted-composition wording may no longer describe the only failing path, but the same IME/caret-offset family still reproduces after committed Chinese input.

    Evidence

    Fresh video would be best here because this depends on the real macOS Chinese IME candidate/commit path:

    CleanShot.2026-05-23.at.00.09.57.mp4

    Suggested browser check

    1. Open a Slate example with normal editable text, such as http://localhost:3100/examples/plaintext.
    2. Place the caret in the middle of existing text.
    3. Use the real macOS Chinese IME to type and commit Chinese text.
    4. Observe whether the caret remains at the expected logical insertion point after commit.
    5. Type one more character to confirm whether the next input inserts at the correct offset.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions