Fix inline rename during IME composition (#519)

This commit is contained in:
Su
2026-08-01 07:45:36 -07:00
committed by GitHub
parent cef6abf5d0
commit 3503a9da8e
3 changed files with 30 additions and 0 deletions
@@ -20,6 +20,7 @@ import {
} from "./context";
import type { TreeNode } from "./common";
import { getNodeKey } from "./common";
import { isImeCompositionEvent } from "./keyboard";
import type { TreeProps } from "./Tree";
import { TreeIndentGuide } from "./TreeIndentGuide";
@@ -170,6 +171,8 @@ function TreeItem_<T extends { id: string }>({
const handleEditKeyDown = useCallback(
async (e: ReactKeyboardEvent<HTMLInputElement>) => {
e.stopPropagation(); // Don't trigger other tree keys (like arrows)
if (isImeCompositionEvent(e.nativeEvent)) return;
switch (e.key) {
case "Enter":
if (editing) {
@@ -0,0 +1,20 @@
import { describe, expect, test } from "vite-plus/test";
import { isImeCompositionEvent } from "./keyboard";
describe("isImeCompositionEvent", () => {
test("detects an active standards-based composition", () => {
expect(isImeCompositionEvent({ isComposing: true, keyCode: 13 })).toBe(true);
});
test("detects the Safari/WebKit key code fallback", () => {
expect(isImeCompositionEvent({ isComposing: false, keyCode: 229 })).toBe(true);
});
test("does not classify an ordinary Enter keydown as composition", () => {
expect(isImeCompositionEvent({ isComposing: false, keyCode: 13 })).toBe(false);
});
test("does not classify an ordinary Escape keydown as composition", () => {
expect(isImeCompositionEvent({ isComposing: false, keyCode: 27 })).toBe(false);
});
});
@@ -0,0 +1,7 @@
export type ImeKeyboardEvent = Pick<KeyboardEvent, "isComposing" | "keyCode">;
export function isImeCompositionEvent(event: ImeKeyboardEvent): boolean {
// Safari can clear `isComposing` on the keydown that finishes composition.
// `229` is retained as the compatibility signal that an IME is processing it.
return event.isComposing || event.keyCode === 229;
}