Respect native input ownership before canvas keyboard cancellation

This commit is contained in:
2026-11-09 19:33:40 +08:00
parent 9efe6e7c9f
commit fd6c166f4b
8 changed files with 70 additions and 10 deletions
+6 -1
View File
@@ -11,6 +11,7 @@ import { NodeStyleToolbar } from "./node-style-toolbar";
import { MembershipBadge } from "./frame-feedback";
import { ContentHandles } from "./content-handles";
import {ownsPointerCapture,acquirePointerCapture,releasePointerCapture} from "@/lib/canvas-bindings/pointer-capture";
import {canvasKeyContext,routeCanvasKey} from "@/lib/canvas-bindings/input-router";
import styles from "./canvas.module.css";
export {NodeEditing} from "./node-editing";
@@ -38,7 +39,11 @@ export function TransformableNode(props: NodeProps<CanvasNode> & { children: Rea
const outside = (event: globalThis.PointerEvent) => {
if (!frame.current?.contains(event.target as Node) && !(event.target as Element).closest?.('[data-rotate-toggle="' + id + '"], [data-resize-toggle="' + id + '"]')) { editing.rotate(null); editing.resize(null); }
};
const escape = (event: KeyboardEvent) => { if (event.key === "Escape" && !event.defaultPrevented && !event.isComposing && !(event.target instanceof Element && event.target.closest('input,textarea,[contenteditable]:not([contenteditable="false"]),[role="textbox"],[role="dialog"],[role="menu"]'))) { cancelGesture(); editing.rotate(null); editing.resize(null); } };
const escape = (event: KeyboardEvent) => {
if(event.key!=="Escape")return;
const claim=routeCanvasKey({key:event.key,composing:event.isComposing,defaultPrevented:event.defaultPrevented,...canvasKeyContext(event)},{tool:()=>{cancelGesture();editing.rotate(null);editing.resize(null);return true;}});
if(claim==='tool'){event.preventDefault();event.stopPropagation();}
};
window.addEventListener("pointerdown", outside, true);
window.addEventListener("keydown", escape);
return () => { window.removeEventListener("pointerdown", outside, true); window.removeEventListener("keydown", escape); };